mhdt_checks.h (36511B)
1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */ 2 /* 3 This file is part of GNU libmicrohttpd. 4 Copyright (C) 2016-2025 Karlson2k (Evgeny Grin) 5 6 GNU libmicrohttpd is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 GNU libmicrohttpd is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 Alternatively, you can redistribute GNU libmicrohttpd and/or 17 modify it under the terms of the GNU General Public License as 18 published by the Free Software Foundation; either version 2 of 19 the License, or (at your option) any later version, together 20 with the eCos exception, as follows: 21 22 As a special exception, if other files instantiate templates or 23 use macros or inline functions from this file, or you compile this 24 file and link it with other works to produce a work based on this 25 file, this file does not by itself cause the resulting work to be 26 covered by the GNU General Public License. However the source code 27 for this file must still be made available in accordance with 28 section (3) of the GNU General Public License v2. 29 30 This exception does not invalidate any other reasons why a work 31 based on this file might be covered by the GNU General Public 32 License. 33 34 You should have received copies of the GNU Lesser General Public 35 License and the GNU General Public License along with this library; 36 if not, see <https://www.gnu.org/licenses/>. 37 */ 38 39 /** 40 * @file src/tests/mhdt_checks.h 41 * @brief MHD test framework helpers 42 * @author Karlson2k (Evgeny Grin) 43 */ 44 #ifndef MHDT_CHECKS_H 45 #define MHDT_CHECKS_H 1 46 47 #include "mhd_sys_options.h" 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <stdint.h> 51 #include <string.h> 52 #ifdef HAVE_INTTYPES_H 53 # include <inttypes.h> 54 #endif 55 56 #if defined(_MSC_VER) 57 #pragma warning(push) 58 /* Disable C4505 "unreferenced local function has been removed" */ 59 #pragma warning(disable:4505) 60 #endif /* _MSC_VER */ 61 62 #ifndef HAVE_SNPRINTF 63 # ifdef _WIN32 64 # define snprintf _snprintf 65 # define HAVE_SNPRINTF 1 66 # endif 67 #endif 68 69 /* 70 * ****** Generic test helpers ****** 71 */ 72 73 #ifdef MHD_HAVE_MHD_FUNC_ 74 # define MHDT_ERR_EXIT() \ 75 do { fprintf (stderr, "\n\n%s:%lu:%s(): Unexpected error exit!\n", \ 76 __FILE__, (unsigned long) __LINE__, MHD_FUNC_); \ 77 fflush (stderr); exit (99);} while (0) 78 # define MHDT_ERR_EXIT_D(desc) \ 79 do { fprintf (stderr, "\n\n%s:%lu:%s(): Unexpected error exit: %s\n", \ 80 __FILE__, (unsigned long) __LINE__, MHD_FUNC_, (desc)); \ 81 fflush (stderr); exit (99);} while (0) 82 #else 83 # define MHDT_ERR_EXIT() \ 84 do { fprintf (stderr, "\n\n%s:%lu: Unexpected error exit!\n", \ 85 __FILE__, (unsigned long) __LINE__); \ 86 fflush (stderr); exit (99);} while (0) 87 # define MHDT_ERR_EXIT_D(desc) \ 88 do { fprintf (stderr, "\n\n%s:%lu: Unexpected error exit: %s\n", \ 89 __FILE__, (unsigned long) __LINE__, (desc)); \ 90 fflush (stderr); exit (99);} while (0) 91 #endif 92 93 /** 94 * Stringify parameter 95 */ 96 #define mhdt_STR_MACRO(x) #x 97 /** 98 * Stringify parameter after expansion 99 */ 100 #define mhdt_STR_MACRO_EXP(x) mhdt_STR_MACRO (x) 101 102 103 /* 104 * ****** Internal data and functions ****** 105 */ 106 107 #define MHDT_NULL_PRNT "[NULL]" 108 109 /** Counter for failed checks within one test */ 110 static unsigned int MHDT_checks_err_counter = 0u; 111 112 /** Counter for total number of failed tests */ 113 static unsigned int MHDT_tests_err_counter = 0u; 114 115 /** Non-zero if current test printed something */ 116 static int MHDT_cur_test_printed_something = 0; 117 118 119 enum MHDT_VerbosityLevelEnum 120 { 121 MHDT_VERB_LVL_SILENT = 0, /**< only failures are printed */ 122 MHDT_VERB_LVL_BASIC = 1, /**< failures and all tests results are printed */ 123 MHDT_VERB_LVL_VERBOSE = 2 /**< all checks and test results are printed */ 124 }; 125 static enum MHDT_VerbosityLevelEnum MHDT_verbosity_level = MHDT_VERB_LVL_BASIC; 126 127 /* Return non-zero if even succeed check result should be printed */ 128 static inline int 129 mhdt_print_check_succeed (void) 130 { 131 return (MHDT_VERB_LVL_VERBOSE <= MHDT_verbosity_level); 132 } 133 134 135 /* Return non-zero if succeed check test should be printed */ 136 static inline int 137 mhdt_print_test_succeed (void) 138 { 139 return (MHDT_VERB_LVL_BASIC <= MHDT_verbosity_level); 140 } 141 142 143 static inline void 144 mhdt_mark_print_in_test_set (void) 145 { 146 if (MHDT_cur_test_printed_something) 147 return; 148 fprintf (stdout, "_____\n"); 149 fflush (stdout); 150 MHDT_cur_test_printed_something = ! 0; 151 } 152 153 154 static inline void 155 mhdt_mark_print_in_test_reset (void) 156 { 157 MHDT_cur_test_printed_something = 0; 158 } 159 160 161 static inline int 162 mhdt_mark_print_in_test_is_set (void) 163 { 164 return MHDT_cur_test_printed_something; 165 } 166 167 168 /* 169 * ****** Configuration functions ****** 170 */ 171 172 static inline void 173 MHDT_set_verbosity (enum MHDT_VerbosityLevelEnum level) 174 { 175 MHDT_verbosity_level = level; 176 } 177 178 179 /* 180 * ****** Functions for getting results ****** 181 */ 182 183 184 /* Return non-zero if succeeded, zero if failed */ 185 static inline int 186 MHDT_test_result (const char *filename, 187 long line, 188 const char *func_name, 189 const char *description) 190 { 191 #ifdef MHD_HAVE_MHD_FUNC_ 192 const int have_func_name = ((NULL != func_name) && (0 != func_name[0])); 193 #else /* ! MHD_HAVE_MHD_FUNC_ */ 194 const int have_func_name = 0; 195 #endif 196 const int have_descr = ((NULL != description) && (0 != description[0])); 197 const int test_succeed = (0u == MHDT_checks_err_counter); 198 199 MHDT_checks_err_counter = 0u; /* Reset the counter for the next test */ 200 201 if (test_succeed && ! mhdt_print_test_succeed ()) 202 return test_succeed; 203 204 fprintf (test_succeed ? stdout : stderr, 205 "%s" 206 "%s:%s%s\n" 207 "%s:%ld: %s%s%s\n\n" 208 "%s", 209 (mhdt_mark_print_in_test_is_set () ? "-----\n" : ""), 210 (test_succeed ? "Succeed" : "FAILED"), 211 (have_descr ? " " : ""), 212 (have_descr ? description : ""), 213 filename, 214 line, 215 (have_func_name ? func_name : ""), 216 (have_func_name ? "(): " : ""), 217 (test_succeed ? "All checks passed" : "Some checks failed"), 218 (mhdt_print_check_succeed () ? "\n" : "")); 219 fflush (test_succeed ? stdout : stderr); 220 mhdt_mark_print_in_test_reset (); 221 222 MHDT_tests_err_counter += (test_succeed ? 0 : 1); 223 224 return test_succeed; 225 } 226 227 228 #define MHDT_TEST_RESULT() \ 229 MHDT_test_result (__FILE__, __LINE__, MHD_FUNC_, NULL) 230 #define MHDT_TEST_RESULT_D(desc) \ 231 MHDT_test_result (__FILE__, __LINE__, MHD_FUNC_, desc) 232 233 234 /* Return ZERO on success, ONE if any test failed */ 235 static inline int 236 MHDT_final_result (const char *exec_selfname, 237 const char *filename) 238 { 239 const char *my_name; 240 const int no_errors = (0u == MHDT_tests_err_counter); 241 242 if ((NULL != exec_selfname) && (0 != exec_selfname[0])) 243 my_name = exec_selfname; 244 else if ((NULL != filename) && (0 != filename[0])) 245 my_name = filename; 246 else 247 my_name = "test"; 248 249 fprintf ((no_errors ? stdout : stderr), 250 "%s: %s\n", 251 (no_errors ? "SUCCEED" : "FAILED"), 252 my_name); 253 254 fflush (no_errors ? stdout : stderr); 255 256 return no_errors ? 0 : 1; 257 } 258 259 260 #define MHDT_FINAL_RESULT(exec_selfname) \ 261 MHDT_final_result (exec_selfname, __FILE__) 262 263 264 /* 265 * ****** Individual checkers ****** 266 */ 267 268 /* Return non-zero if succeeded, zero if failed */ 269 static inline int 270 MHDT_check_bool (int result, 271 int expected, 272 const char *check_str, 273 const char *check_str_exp, 274 const char *filename, 275 long line, 276 const char *func_name, 277 const char *description) 278 { 279 #ifdef MHD_HAVE_MHD_FUNC_ 280 const int have_func_name = ((NULL != func_name) && (0 != func_name[0])); 281 #else /* ! MHD_HAVE_MHD_FUNC_ */ 282 const int have_func_name = 0; 283 #endif 284 const int have_descr = ((NULL != description) && (0 != description[0])); 285 int exp_different; 286 int check_succeed; 287 288 check_succeed = ((! ! result) == (! ! expected)); 289 290 if (check_succeed && ! mhdt_print_check_succeed ()) 291 return check_succeed; 292 293 mhdt_mark_print_in_test_set (); 294 exp_different = (0 != strcmp (check_str, check_str_exp)); 295 fprintf (check_succeed ? stdout : stderr, 296 "%s:%s%s\n" 297 "%s:%ld: %s%sthe result of the evaluation of the\n" 298 "\texpression: '%s'%s%s%s\n" 299 "\tActual: '%s'\tExpected: '%s'\n", 300 (check_succeed ? "Pass" : "FAIL"), 301 (have_descr ? " " : ""), 302 (have_descr ? description : ""), 303 filename, 304 line, 305 (have_func_name ? func_name : ""), 306 (have_func_name ? "(): " : ""), 307 check_str, 308 (exp_different ? "\n\texpanded: '" : ""), 309 (exp_different ? check_str_exp : ""), 310 (exp_different ? "'" : ""), 311 ((! ! result) ? "NON-zero" : "ZERO"), 312 ((! ! expected) ? "NON-zero" : "ZERO")); 313 fflush (check_succeed ? stdout : stderr); 314 315 MHDT_checks_err_counter += (check_succeed ? 0 : 1); 316 317 return check_succeed; 318 } 319 320 321 #define MHDT_EXPECT_TRUE(cond) \ 322 MHDT_check_bool ((cond), ! 0, #cond, \ 323 mhdt_STR_MACRO_EXP (cond), __FILE__, __LINE__, \ 324 MHD_FUNC_, NULL) 325 #define MHDT_EXPECT_FALSE(cond) \ 326 MHDT_check_bool ((cond), 0, #cond, \ 327 mhdt_STR_MACRO_EXP (cond), __FILE__, __LINE__, \ 328 MHD_FUNC_, NULL) 329 330 #define MHDT_EXPECT_TRUE_D(cond, desc) \ 331 MHDT_check_bool ((cond), ! 0, #cond, \ 332 mhdt_STR_MACRO_EXP (cond), __FILE__, __LINE__, \ 333 MHD_FUNC_, desc) 334 #define MHDT_EXPECT_FALSE_D(cond, desc) \ 335 MHDT_check_bool ((cond), 0, #cond, \ 336 mhdt_STR_MACRO_EXP (cond), __FILE__, __LINE__, \ 337 MHD_FUNC_, desc) 338 339 #define MHDT_ASSERT MHDT_EXPECT_TRUE 340 #define MHDT_ASSERT_D MHDT_EXPECT_TRUE_D 341 342 /* Return non-zero if succeeded, zero if failed */ 343 static inline int 344 MHDT_check_ptr (const void *ptr, 345 int expected_non_null, 346 const char *check_str, 347 const char *check_str_exp, 348 const char *filename, 349 long line, 350 const char *func_name, 351 const char *description) 352 { 353 #ifdef MHD_HAVE_MHD_FUNC_ 354 const int have_func_name = ((NULL != func_name) && (0 != func_name[0])); 355 #else /* ! MHD_HAVE_MHD_FUNC_ */ 356 const int have_func_name = 0; 357 #endif 358 const int have_descr = ((NULL != description) && (0 != description[0])); 359 int exp_different; 360 int check_succeed; 361 362 check_succeed = ((NULL != ptr) == (! ! expected_non_null)); 363 364 if (check_succeed && ! mhdt_print_check_succeed ()) 365 return check_succeed; 366 367 mhdt_mark_print_in_test_set (); 368 exp_different = (0 != strcmp (check_str, check_str_exp)); 369 fprintf (check_succeed ? stdout : stderr, 370 "%s:%s%s\n" 371 "%s:%ld: %s%sthe value of the\n" 372 "\tpointer: '%s'%s%s%s\n" 373 "\tActual: '%s'\tExpected: '%s'\n", 374 (check_succeed ? "Pass" : "FAIL"), 375 (have_descr ? " " : ""), 376 (have_descr ? description : ""), 377 filename, 378 line, 379 (have_func_name ? func_name : ""), 380 (have_func_name ? "(): " : ""), 381 check_str, 382 (exp_different ? "\n\texpanded: '" : ""), 383 (exp_different ? check_str_exp : ""), 384 (exp_different ? "'" : ""), 385 ((NULL != ptr) ? "non-NULL" : "NULL"), 386 ((! ! expected_non_null) ? "non-NULL" : "NULL")); 387 fflush (check_succeed ? stdout : stderr); 388 389 MHDT_checks_err_counter += (check_succeed ? 0 : 1); 390 391 return check_succeed; 392 } 393 394 395 #define MHDT_EXPECT_PTR_NULL(ptr) \ 396 MHDT_check_ptr ((ptr), 0, #ptr, \ 397 mhdt_STR_MACRO_EXP (ptr), __FILE__, __LINE__, MHD_FUNC_, \ 398 NULL) 399 #define MHDT_EXPECT_PTR_NONNULL(ptr) \ 400 MHDT_check_ptr ((ptr), ! 0, #ptr, \ 401 mhdt_STR_MACRO_EXP (ptr), __FILE__, __LINE__, MHD_FUNC_, \ 402 NULL) 403 404 #define MHDT_EXPECT_PTR_NULL_D(ptr, desc) \ 405 MHDT_check_ptr ((ptr), 0, #ptr, \ 406 mhdt_STR_MACRO_EXP (ptr), __FILE__, __LINE__, MHD_FUNC_, \ 407 desc) 408 #define MHDT_EXPECT_PTR_NONNULL_D(ptr, desc) \ 409 MHDT_check_ptr ((ptr), ! 0, #ptr, \ 410 mhdt_STR_MACRO_EXP (ptr), __FILE__, __LINE__, MHD_FUNC_, \ 411 desc) 412 413 #ifdef PRIuMAX 414 typedef uintmax_t mhdt_uint_t; 415 # define MHDT_UINT_PRI PRIuMAX 416 # define MHDT_UINT_PRI_CAST(val) val 417 #elif defined(PRIuFAST64) 418 typedef uint_fast64_t mhdt_uint_t; 419 # define MHDT_UINT_PRI PRIuFAST64 420 # define MHDT_UINT_PRI_CAST(val) val 421 #else 422 typedef uint_fast64_t mhdt_uint_t; 423 # define MHDT_UINT_PRI "lu" 424 # define MHDT_UINT_PRI_CAST(val) ((unsigned long) val) 425 #endif 426 427 /** 428 * Comparison type 429 */ 430 enum mhdt_CmpType 431 { 432 MHDT_CMP_EQ,/**< a == b */ 433 MHDT_CMP_LT,/**< a < b */ 434 MHDT_CMP_LE,/**< a <= b */ 435 MHDT_CMP_NE,/**< a != b */ 436 MHDT_CMP_GE,/**< a >= b */ 437 MHDT_CMP_GT,/**< a > b */ 438 }; 439 440 441 /* Return non-zero if succeeded, zero if failed */ 442 static inline int 443 MHDT_check_ui_cmp (mhdt_uint_t val_a, 444 enum mhdt_CmpType cmp_t, 445 mhdt_uint_t val_b, 446 const char *val_a_str, 447 const char *val_b_str, 448 const char *val_a_str_exp, 449 const char *val_b_str_exp, 450 const char *filename, 451 long line, 452 const char *func_name, 453 const char *description) 454 { 455 #ifdef MHD_HAVE_MHD_FUNC_ 456 const int have_func_name = ((NULL != func_name) && (0 != func_name[0])); 457 #else /* ! MHD_HAVE_MHD_FUNC_ */ 458 const int have_func_name = 0; 459 #endif 460 const int have_descr = ((NULL != description) && (0 != description[0])); 461 char val_a_buf[512] = ""; 462 char val_b_buf[512] = ""; 463 int use_buf_print = 0; 464 int str_has_suff; 465 int both_str_has_suff; 466 const size_t buf_size = (sizeof(val_a_buf) / sizeof(char)); 467 const char *cmp_str; 468 int check_succeed; 469 470 switch (cmp_t) 471 { 472 case MHDT_CMP_EQ: 473 check_succeed = (val_a == val_b); 474 cmp_str = "=="; 475 break; 476 case MHDT_CMP_LT: 477 check_succeed = (val_a < val_b); 478 cmp_str = "<"; 479 break; 480 case MHDT_CMP_LE: 481 check_succeed = (val_a <= val_b); 482 cmp_str = "<="; 483 break; 484 case MHDT_CMP_NE: 485 check_succeed = (val_a != val_b); 486 cmp_str = "!="; 487 break; 488 case MHDT_CMP_GE: 489 check_succeed = (val_a >= val_b); 490 cmp_str = ">="; 491 break; 492 case MHDT_CMP_GT: 493 check_succeed = (val_a > val_b); 494 cmp_str = ">"; 495 break; 496 default: 497 MHDT_ERR_EXIT (); 498 break; 499 } 500 501 if (check_succeed && ! mhdt_print_check_succeed ()) 502 return check_succeed; 503 504 both_str_has_suff = ! 0; 505 str_has_suff = 0; 506 if (1) /* For local scope */ 507 { 508 const mhdt_uint_t val = val_a; 509 char *const print_buf = val_a_buf; 510 const char *const str = val_a_str_exp; 511 int print_res; 512 513 print_res = 514 #ifdef HAVE_SNPRINTF 515 snprintf (print_buf, buf_size, 516 #else 517 sprintf (print_buf, 518 #endif 519 "%" MHDT_UINT_PRI, 520 MHDT_UINT_PRI_CAST (val)); 521 if ((0 > print_res) || 522 (buf_size <= (unsigned int) print_res)) 523 MHDT_ERR_EXIT (); 524 525 if (0 != strcmp (str, print_buf)) 526 { 527 const size_t str_len = strlen (str); 528 if (str_len - 1 != (unsigned int) print_res) 529 use_buf_print = ! 0; 530 else if ((('u' == str[str_len - 1u]) || ('U' == str[str_len - 1u])) 531 && (0 == memcmp (str, print_buf, str_len - 1u))) 532 str_has_suff = ! 0; 533 else 534 use_buf_print = ! 0; 535 } 536 else 537 both_str_has_suff = 0; 538 } 539 if (1) /* For local scope */ 540 { 541 const mhdt_uint_t val = val_b; 542 char *const print_buf = val_b_buf; 543 const char *const str = val_b_str_exp; 544 int print_res; 545 546 print_res = 547 #ifdef HAVE_SNPRINTF 548 snprintf (print_buf, buf_size, 549 #else 550 sprintf (print_buf, 551 #endif 552 "%" MHDT_UINT_PRI, 553 MHDT_UINT_PRI_CAST (val)); 554 if ((0 > print_res) || 555 (buf_size <= (unsigned int) print_res)) 556 MHDT_ERR_EXIT (); 557 558 if (0 != strcmp (str, print_buf)) 559 { 560 const size_t str_len = strlen (str); 561 if (str_len - 1 != (unsigned int) print_res) 562 use_buf_print = ! 0; 563 else if ((('u' == str[str_len - 1u]) || ('U' == str[str_len - 1u])) 564 && (0 == memcmp (str, print_buf, str_len - 1u))) 565 str_has_suff = ! 0; 566 else 567 use_buf_print = ! 0; 568 } 569 else 570 both_str_has_suff = 0; 571 } 572 if (! use_buf_print && str_has_suff && ! both_str_has_suff) 573 use_buf_print = ! 0; 574 575 mhdt_mark_print_in_test_set (); 576 fprintf (check_succeed ? stdout : stderr, 577 "%s:%s%s\n" 578 "%s:%ld: %s%sThe %s check:\n" 579 "\toriginal: '%s %s %s'\n", 580 (check_succeed ? "Pass" : "FAIL"), 581 (have_descr ? " " : ""), 582 (have_descr ? description : ""), 583 filename, 584 line, 585 (have_func_name ? func_name : ""), 586 (have_func_name ? "(): " : ""), 587 (check_succeed ? "passed" : "failed"), 588 val_a_str, cmp_str, val_b_str); 589 if ((0 != strcmp (val_a_str, val_a_str_exp)) || 590 (0 != strcmp (val_b_str, val_b_str_exp))) 591 fprintf (check_succeed ? stdout : stderr, 592 "\texpanded: '%s %s %s'\n", 593 val_a_str_exp, cmp_str, val_b_str_exp); 594 if (use_buf_print) 595 fprintf (check_succeed ? stdout : stderr, 596 "\tvalues: '%s %s %s'\n", 597 val_a_buf, cmp_str, val_b_buf); 598 599 fflush (check_succeed ? stdout : stderr); 600 601 MHDT_checks_err_counter += (check_succeed ? 0 : 1); 602 603 return check_succeed; 604 } 605 606 607 #define MHDT_EXPECT_UINT_EQ_VAL(uiv_l,uiv_r) \ 608 MHDT_check_ui_cmp ((uiv_l), MHDT_CMP_EQ, (uiv_r), \ 609 #uiv_l, #uiv_r, \ 610 mhdt_STR_MACRO_EXP (uiv_l), \ 611 mhdt_STR_MACRO_EXP (uiv_r), \ 612 __FILE__, __LINE__, MHD_FUNC_, NULL) 613 #define MHDT_EXPECT_UINT_LT_VAL(uiv_l,uiv_r) \ 614 MHDT_check_ui_cmp ((uiv_l), MHDT_CMP_LT, (uiv_r), \ 615 #uiv_l, #uiv_r, \ 616 mhdt_STR_MACRO_EXP (uiv_l), \ 617 mhdt_STR_MACRO_EXP (uiv_r), \ 618 __FILE__, __LINE__, MHD_FUNC_, NULL) 619 #define MHDT_EXPECT_UINT_LE_VAL(uiv_l,uiv_r) \ 620 MHDT_check_ui_cmp ((uiv_l), MHDT_CMP_LE, (uiv_r), \ 621 #uiv_l, #uiv_r, \ 622 mhdt_STR_MACRO_EXP (uiv_l), \ 623 mhdt_STR_MACRO_EXP (uiv_r), \ 624 __FILE__, __LINE__, MHD_FUNC_, NULL) 625 #define MHDT_EXPECT_UINT_NE_VAL(uiv_l,uiv_r) \ 626 MHDT_check_ui_cmp ((uiv_l), MHDT_CMP_NE, (uiv_r), \ 627 #uiv_l, #uiv_r, \ 628 mhdt_STR_MACRO_EXP (uiv_l), \ 629 mhdt_STR_MACRO_EXP (uiv_r), \ 630 __FILE__, __LINE__, MHD_FUNC_, NULL) 631 #define MHDT_EXPECT_UINT_GE_VAL(uiv_l,uiv_r) \ 632 MHDT_check_ui_cmp ((uiv_l), MHDT_CMP_GE, (uiv_r), \ 633 #uiv_l, #uiv_r, \ 634 mhdt_STR_MACRO_EXP (uiv_l), \ 635 mhdt_STR_MACRO_EXP (uiv_r), \ 636 __FILE__, __LINE__, MHD_FUNC_, NULL) 637 #define MHDT_EXPECT_UINT_GT_VAL(uiv_l,uiv_r) \ 638 MHDT_check_ui_cmp ((uiv_l), MHDT_CMP_GT, (uiv_r), \ 639 #uiv_l, #uiv_r, \ 640 mhdt_STR_MACRO_EXP (uiv_l), \ 641 mhdt_STR_MACRO_EXP (uiv_r), \ 642 __FILE__, __LINE__, MHD_FUNC_, NULL) 643 644 #define MHDT_EXPECT_UINT_EQ_VAL_D(uiv_l,uiv_r,desc) \ 645 MHDT_check_ui_cmp ((uiv_l), MHDT_CMP_EQ, (uiv_r), \ 646 #uiv_l, #uiv_r, \ 647 mhdt_STR_MACRO_EXP (uiv_l), \ 648 mhdt_STR_MACRO_EXP (uiv_r), \ 649 __FILE__, __LINE__, MHD_FUNC_, desc) 650 #define MHDT_EXPECT_UINT_LT_VAL_D(uiv_l,uiv_r,desc) \ 651 MHDT_check_ui_cmp ((uiv_l), MHDT_CMP_LT, (uiv_r), \ 652 #uiv_l, #uiv_r, \ 653 mhdt_STR_MACRO_EXP (uiv_l), \ 654 mhdt_STR_MACRO_EXP (uiv_r), \ 655 __FILE__, __LINE__, MHD_FUNC_, desc) 656 #define MHDT_EXPECT_UINT_LE_VAL_D(uiv_l,uiv_r,desc) \ 657 MHDT_check_ui_cmp ((uiv_l), MHDT_CMP_LE, (uiv_r), \ 658 #uiv_l, #uiv_r, \ 659 mhdt_STR_MACRO_EXP (uiv_l), \ 660 mhdt_STR_MACRO_EXP (uiv_r), \ 661 __FILE__, __LINE__, MHD_FUNC_, desc) 662 #define MHDT_EXPECT_UINT_NE_VAL_D(uiv_l,uiv_r,desc) \ 663 MHDT_check_ui_cmp ((uiv_l), MHDT_CMP_NE, (uiv_r), \ 664 #uiv_l, #uiv_r, \ 665 mhdt_STR_MACRO_EXP (uiv_l), \ 666 mhdt_STR_MACRO_EXP (uiv_r), \ 667 __FILE__, __LINE__, MHD_FUNC_, desc) 668 #define MHDT_EXPECT_UINT_GE_VAL_D(uiv_l,uiv_r,desc) \ 669 MHDT_check_ui_cmp ((uiv_l), MHDT_CMP_GE, (uiv_r), \ 670 #uiv_l, #uiv_r, \ 671 mhdt_STR_MACRO_EXP (uiv_l), \ 672 mhdt_STR_MACRO_EXP (uiv_r), \ 673 __FILE__, __LINE__, MHD_FUNC_, desc) 674 #define MHDT_EXPECT_UINT_GT_VAL_D(uiv_l,uiv_r,desc) \ 675 MHDT_check_ui_cmp ((uiv_l), MHDT_CMP_GT, (uiv_r), \ 676 #uiv_l, #uiv_r, \ 677 mhdt_STR_MACRO_EXP (uiv_l), \ 678 mhdt_STR_MACRO_EXP (uiv_r), \ 679 __FILE__, __LINE__, MHD_FUNC_, desc) 680 681 682 #ifdef PRIdMAX 683 typedef intmax_t mhdt_int_t; 684 # define MHDT_INT_PRI PRIdMAX 685 # define MHDT_INT_PRI_CAST(val) val 686 #elif defined(PRIdFAST64) 687 typedef int_fast64_t mhdt_int_t; 688 # define MHDT_INT_PRI PRIdFAST64 689 # define MHDT_INT_PRI_CAST(val) val 690 #else 691 typedef int_fast64_t mhdt_int_t; 692 # define MHDT_INT_PRI "ld" 693 # define MHDT_INT_PRI_CAST(val) ((long) val) 694 #endif 695 696 697 /* Return non-zero if succeeded, zero if failed */ 698 static inline int 699 MHDT_check_i_cmp (mhdt_int_t val_a, 700 enum mhdt_CmpType cmp_t, 701 mhdt_int_t val_b, 702 const char *val_a_str, 703 const char *val_b_str, 704 const char *val_a_str_exp, 705 const char *val_b_str_exp, 706 const char *filename, 707 long line, 708 const char *func_name, 709 const char *description) 710 { 711 #ifdef MHD_HAVE_MHD_FUNC_ 712 const int have_func_name = ((NULL != func_name) && (0 != func_name[0])); 713 #else /* ! MHD_HAVE_MHD_FUNC_ */ 714 const int have_func_name = 0; 715 #endif 716 const int have_descr = ((NULL != description) && (0 != description[0])); 717 char val_a_buf[512] = ""; 718 char val_b_buf[512] = ""; 719 int use_buf_print = 0; 720 const size_t buf_size = (sizeof(val_a_buf) / sizeof(char)); 721 const char *cmp_str; 722 int check_succeed; 723 724 switch (cmp_t) 725 { 726 case MHDT_CMP_EQ: 727 check_succeed = (val_a == val_b); 728 cmp_str = "=="; 729 break; 730 case MHDT_CMP_LT: 731 check_succeed = (val_a < val_b); 732 cmp_str = "<"; 733 break; 734 case MHDT_CMP_LE: 735 check_succeed = (val_a <= val_b); 736 cmp_str = "<="; 737 break; 738 case MHDT_CMP_NE: 739 check_succeed = (val_a != val_b); 740 cmp_str = "!="; 741 break; 742 case MHDT_CMP_GE: 743 check_succeed = (val_a >= val_b); 744 cmp_str = ">="; 745 break; 746 case MHDT_CMP_GT: 747 check_succeed = (val_a > val_b); 748 cmp_str = ">"; 749 break; 750 default: 751 MHDT_ERR_EXIT (); 752 break; 753 } 754 755 if (check_succeed && ! mhdt_print_check_succeed ()) 756 return check_succeed; 757 758 if (1) /* For local scope */ 759 { 760 const mhdt_int_t val = val_a; 761 char *const print_buf = val_a_buf; 762 const char *const str = val_a_str_exp; 763 int print_res; 764 765 print_res = 766 #ifdef HAVE_SNPRINTF 767 snprintf (print_buf, buf_size, 768 #else 769 sprintf (print_buf, 770 #endif 771 "%" MHDT_INT_PRI, 772 MHDT_INT_PRI_CAST (val)); 773 if ((0 > print_res) || 774 (buf_size <= (unsigned int) print_res)) 775 MHDT_ERR_EXIT (); 776 777 if (0 != strcmp (str, print_buf)) 778 use_buf_print = ! 0; 779 } 780 if (1) /* For local scope */ 781 { 782 const mhdt_int_t val = val_b; 783 char *const print_buf = val_b_buf; 784 const char *const str = val_b_str_exp; 785 int print_res; 786 787 print_res = 788 #ifdef HAVE_SNPRINTF 789 snprintf (print_buf, buf_size, 790 #else 791 sprintf (print_buf, 792 #endif 793 "%" MHDT_INT_PRI, 794 MHDT_INT_PRI_CAST (val)); 795 if ((0 > print_res) || 796 (buf_size <= (unsigned int) print_res)) 797 MHDT_ERR_EXIT (); 798 799 if (0 != strcmp (str, print_buf)) 800 use_buf_print = ! 0; 801 } 802 803 mhdt_mark_print_in_test_set (); 804 fprintf (check_succeed ? stdout : stderr, 805 "%s:%s%s\n" 806 "%s:%ld: %s%sThe %s check:\n" 807 "\toriginal: '%s %s %s'\n", 808 (check_succeed ? "Pass" : "FAIL"), 809 (have_descr ? " " : ""), 810 (have_descr ? description : ""), 811 filename, 812 line, 813 (have_func_name ? func_name : ""), 814 (have_func_name ? "(): " : ""), 815 (check_succeed ? "passed" : "failed"), 816 val_a_str, cmp_str, val_b_str); 817 if ((0 != strcmp (val_a_str, val_a_str_exp)) || 818 (0 != strcmp (val_b_str, val_b_str_exp))) 819 fprintf (check_succeed ? stdout : stderr, 820 "\texpanded: '%s %s %s'\n", 821 val_a_str_exp, cmp_str, val_b_str_exp); 822 if (use_buf_print) 823 fprintf (check_succeed ? stdout : stderr, 824 "\tvalues: '%s %s %s'\n", 825 val_a_buf, cmp_str, val_b_buf); 826 827 fflush (check_succeed ? stdout : stderr); 828 829 MHDT_checks_err_counter += (check_succeed ? 0 : 1); 830 831 return check_succeed; 832 } 833 834 835 #define MHDT_EXPECT_INT_EQ_VAL(iv_l,iv_r) \ 836 MHDT_check_i_cmp ((iv_l), MHDT_CMP_EQ, (iv_r), \ 837 #iv_l, #iv_r, \ 838 mhdt_STR_MACRO_EXP (iv_l), mhdt_STR_MACRO_EXP (iv_r), \ 839 __FILE__, __LINE__, MHD_FUNC_, NULL) 840 #define MHDT_EXPECT_INT_LT_VAL(iv_l,iv_r) \ 841 MHDT_check_i_cmp ((iv_l), MHDT_CMP_LT, (iv_r), \ 842 #iv_l, #iv_r, \ 843 mhdt_STR_MACRO_EXP (iv_l), mhdt_STR_MACRO_EXP (iv_r), \ 844 __FILE__, __LINE__, MHD_FUNC_, NULL) 845 #define MHDT_EXPECT_INT_LE_VAL(iv_l,iv_r) \ 846 MHDT_check_i_cmp ((iv_l), MHDT_CMP_LE, (iv_r), \ 847 #iv_l, #iv_r, \ 848 mhdt_STR_MACRO_EXP (iv_l), mhdt_STR_MACRO_EXP (iv_r), \ 849 __FILE__, __LINE__, MHD_FUNC_, NULL) 850 #define MHDT_EXPECT_INT_NE_VAL(iv_l,iv_r) \ 851 MHDT_check_i_cmp ((iv_l), MHDT_CMP_NE, (iv_r), \ 852 #iv_l, #iv_r, \ 853 mhdt_STR_MACRO_EXP (iv_l), mhdt_STR_MACRO_EXP (iv_r), \ 854 __FILE__, __LINE__, MHD_FUNC_, NULL) 855 #define MHDT_EXPECT_INT_GE_VAL(iv_l,iv_r) \ 856 MHDT_check_i_cmp ((iv_l), MHDT_CMP_GE, (iv_r), \ 857 #iv_l, #iv_r, \ 858 mhdt_STR_MACRO_EXP (iv_l), mhdt_STR_MACRO_EXP (iv_r), \ 859 __FILE__, __LINE__, MHD_FUNC_, NULL) 860 #define MHDT_EXPECT_INT_GT_VAL(iv_l,iv_r) \ 861 MHDT_check_i_cmp ((iv_l), MHDT_CMP_GT, (iv_r), \ 862 #iv_l, #iv_r, \ 863 mhdt_STR_MACRO_EXP (iv_l), mhdt_STR_MACRO_EXP (iv_r), \ 864 __FILE__, __LINE__, MHD_FUNC_, NULL) 865 866 #define MHDT_EXPECT_INT_EQ_VAL_D(iv_l,iv_r,desc) \ 867 MHDT_check_i_cmp ((iv_l), MHDT_CMP_EQ, (iv_r), \ 868 #iv_l, #iv_r, \ 869 mhdt_STR_MACRO_EXP (iv_l), mhdt_STR_MACRO_EXP (iv_r), \ 870 __FILE__, __LINE__, MHD_FUNC_, desc) 871 #define MHDT_EXPECT_INT_LT_VAL_D(iv_l,iv_r,desc) \ 872 MHDT_check_i_cmp ((iv_l), MHDT_CMP_LT, (iv_r), \ 873 #iv_l, #iv_r, \ 874 mhdt_STR_MACRO_EXP (iv_l), mhdt_STR_MACRO_EXP (iv_r), \ 875 __FILE__, __LINE__, MHD_FUNC_, desc) 876 #define MHDT_EXPECT_INT_LE_VAL_D(iv_l,iv_r,desc) \ 877 MHDT_check_i_cmp ((iv_l), MHDT_CMP_LE, (iv_r), \ 878 #iv_l, #iv_r, \ 879 mhdt_STR_MACRO_EXP (iv_l), mhdt_STR_MACRO_EXP (iv_r), \ 880 __FILE__, __LINE__, MHD_FUNC_, desc) 881 #define MHDT_EXPECT_INT_NE_VAL_D(iv_l,iv_r,desc) \ 882 MHDT_check_i_cmp ((iv_l), MHDT_CMP_NE, (iv_r), \ 883 #iv_l, #iv_r, \ 884 mhdt_STR_MACRO_EXP (iv_l), mhdt_STR_MACRO_EXP (iv_r), \ 885 __FILE__, __LINE__, MHD_FUNC_, desc) 886 #define MHDT_EXPECT_INT_GE_VAL_D(iv_l,iv_r,desc) \ 887 MHDT_check_i_cmp ((iv_l), MHDT_CMP_GE, (iv_r), \ 888 #iv_l, #iv_r, \ 889 mhdt_STR_MACRO_EXP (iv_l), mhdt_STR_MACRO_EXP (iv_r), \ 890 __FILE__, __LINE__, MHD_FUNC_, desc) 891 #define MHDT_EXPECT_INT_GT_VAL_D(iv_l,iv_r,desc) \ 892 MHDT_check_i_cmp ((iv_l), MHDT_CMP_GT, (iv_r), \ 893 #iv_l, #iv_r, \ 894 mhdt_STR_MACRO_EXP (iv_l), mhdt_STR_MACRO_EXP (iv_r), \ 895 __FILE__, __LINE__, MHD_FUNC_, desc) 896 897 898 /* Return non-zero if succeeded, zero if failed */ 899 static MHD_FN_PAR_CSTR_ (1) MHD_FN_PAR_CSTR_ (2) inline int 900 MHDT_check_str (const char *result, 901 const char *expected, 902 const char *check_str, 903 const char *check_str_exp, 904 const char *filename, 905 long line, 906 const char *func_name, 907 const char *description) 908 { 909 #ifdef MHD_HAVE_MHD_FUNC_ 910 const int have_func_name = ((NULL != func_name) && (0 != func_name[0])); 911 #else /* ! MHD_HAVE_MHD_FUNC_ */ 912 const int have_func_name = 0; 913 #endif 914 const int have_descr = ((NULL != description) && (0 != description[0])); 915 int exp_different; 916 int check_succeed; 917 918 if (NULL == expected) 919 MHDT_ERR_EXIT_D ("'expected' must not be NULL"); 920 921 check_succeed = ((NULL != result) && (0 == strcmp (result, expected))); 922 923 if (check_succeed && ! mhdt_print_check_succeed ()) 924 return check_succeed; 925 926 mhdt_mark_print_in_test_set (); 927 exp_different = (0 != strcmp (check_str, check_str_exp)); 928 fprintf (check_succeed ? stdout : stderr, 929 "%s:%s%s\n" 930 "%s:%ld: %s%sThe value of '%s'%s%s%s:\n" 931 "\tActual: \"%s\"\tExpected: \"%s\"\n", 932 (check_succeed ? "Pass" : "FAIL"), 933 (have_descr ? " " : ""), 934 (have_descr ? description : ""), 935 filename, 936 line, 937 (have_func_name ? func_name : ""), 938 (have_func_name ? "(): " : ""), 939 check_str, 940 (exp_different ? " (expanded: '" : ""), 941 (exp_different ? check_str_exp : ""), 942 (exp_different ? "')" : ""), 943 ((NULL == result) ? MHDT_NULL_PRNT : result), 944 expected); 945 fflush (check_succeed ? stdout : stderr); 946 947 MHDT_checks_err_counter += (check_succeed ? 0 : 1); 948 949 return check_succeed; 950 } 951 952 953 #define MHDT_EXPECT_STR_EQ(str, expected) \ 954 MHDT_check_str ((str), (expected), \ 955 #str, mhdt_STR_MACRO_EXP (str), \ 956 __FILE__, __LINE__, MHD_FUNC_, \ 957 NULL) 958 #define MHDT_EXPECT_STR_EQ_D(str, expected, desc) \ 959 MHDT_check_str ((str), (expected), \ 960 #str, mhdt_STR_MACRO_EXP (str), \ 961 __FILE__, __LINE__, MHD_FUNC_, \ 962 desc) 963 964 /* 'result' must not be NULL */ 965 /* Return non-zero if succeeded, zero if failed */ 966 static MHD_FN_PAR_CSTR_ (3) inline int 967 MHDT_check_strn_str (size_t result_len, 968 const char *result, 969 const char *expected, 970 const char *filename, 971 long line, 972 const char *func_name, 973 const char *description) 974 { 975 #ifdef MHD_HAVE_MHD_FUNC_ 976 const int have_func_name = ((NULL != func_name) && (0 != func_name[0])); 977 #else /* ! MHD_HAVE_MHD_FUNC_ */ 978 const int have_func_name = 0; 979 #endif 980 const int have_descr = ((NULL != description) && (0 != description[0])); 981 int check_succeed; 982 983 if (NULL == expected) 984 MHDT_ERR_EXIT_D ("'expected' must not be NULL"); 985 986 check_succeed = ((NULL != result) 987 && (result_len == strlen (expected)) 988 && (0 == memcmp (result, expected, result_len))); 989 990 if (check_succeed && ! mhdt_print_check_succeed ()) 991 return check_succeed; 992 993 mhdt_mark_print_in_test_set (); 994 fprintf (check_succeed ? stdout : stderr, 995 "%s:%s%s\n" 996 "%s:%ld: %s%s\n" 997 "\tActual: \"%.*s\" (len: %lu)" /* mis-print binary zero */ 998 "\tExpected: \"%s\" (len: %lu)\n", 999 (check_succeed ? "Pass" : "FAIL"), 1000 (have_descr ? " " : ""), 1001 (have_descr ? description : ""), 1002 filename, 1003 line, 1004 (have_func_name ? func_name : ""), 1005 (have_func_name ? "(): " : ""), 1006 (int) (result ? result_len : strlen (MHDT_NULL_PRNT)), 1007 (result ? result : MHDT_NULL_PRNT), (unsigned long) result_len, 1008 expected, (unsigned long) strlen (expected)); 1009 fflush (check_succeed ? stdout : stderr); 1010 1011 MHDT_checks_err_counter += (check_succeed ? 0 : 1); 1012 1013 return check_succeed; 1014 } 1015 1016 1017 #define MHDT_EXPECT_STRN_EQ_STR_D(str_len, str, expected, desc) \ 1018 MHDT_check_strn_str ((str_len), (str), (expected), \ 1019 __FILE__, __LINE__, MHD_FUNC_, \ 1020 desc) 1021 1022 1023 /* if 'result_len' is zero then 'result' is ignored */ 1024 /* Return non-zero if succeeded, zero if failed */ 1025 static inline int 1026 MHDT_check_strn (size_t result_len, 1027 const char *result, 1028 size_t expected_len, 1029 const char *expected, 1030 const char *filename, 1031 long line, 1032 const char *func_name, 1033 const char *description) 1034 { 1035 #ifdef MHD_HAVE_MHD_FUNC_ 1036 const int have_func_name = ((NULL != func_name) && (0 != func_name[0])); 1037 #else /* ! MHD_HAVE_MHD_FUNC_ */ 1038 const int have_func_name = 0; 1039 #endif 1040 const int have_descr = ((NULL != description) && (0 != description[0])); 1041 int check_succeed; 1042 1043 if ((NULL == expected) && (0u != expected_len)) 1044 MHDT_ERR_EXIT_D ("'expected' must not be NULL or " \ 1045 "'expected_len' must be zero "); 1046 1047 check_succeed = (result_len == expected_len); 1048 if (check_succeed && (0u != expected_len)) 1049 check_succeed = (0 == memcmp (result, expected, result_len)); 1050 1051 if (check_succeed && ! mhdt_print_check_succeed ()) 1052 return check_succeed; 1053 1054 mhdt_mark_print_in_test_set (); 1055 fprintf (check_succeed ? stdout : stderr, 1056 "%s:%s%s\n" 1057 "%s:%ld: %s%s\n" 1058 "\tActual: \"%.*s\" (len: %lu)" /* mis-print binary zero */ 1059 "\tExpected: \"%.*s\" (len: %lu)\n", /* mis-print binary zero */ 1060 (check_succeed ? "Pass" : "FAIL"), 1061 (have_descr ? " " : ""), 1062 (have_descr ? description : ""), 1063 filename, 1064 line, 1065 (have_func_name ? func_name : ""), 1066 (have_func_name ? "(): " : ""), 1067 (int) (result ? result_len : strlen (MHDT_NULL_PRNT)), 1068 (result ? result : MHDT_NULL_PRNT), (unsigned long) result_len, 1069 (int) (expected ? expected_len : strlen (MHDT_NULL_PRNT)), 1070 (expected ? expected : MHDT_NULL_PRNT), 1071 (unsigned long) expected_len); 1072 fflush (check_succeed ? stdout : stderr); 1073 1074 MHDT_checks_err_counter += (check_succeed ? 0 : 1); 1075 1076 return check_succeed; 1077 } 1078 1079 1080 #define MHDT_EXPECT_STRN_EQ_D(str_len, str, expected_len, expected, desc) \ 1081 MHDT_check_strn ((str_len), (str), (expected_len), (expected), \ 1082 __FILE__, __LINE__, MHD_FUNC_, \ 1083 desc) 1084 1085 1086 1087 1088 #if defined(_MSC_VER) 1089 /* Restore warnings */ 1090 #pragma warning(pop) 1091 #endif /* _MSC_VER */ 1092 1093 #endif /* ! MHDT_CHECKS_H */