unity.c (49356B)
1 /* ========================================================================= 2 Unity Project - A Test Framework for C 3 Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams 4 [Released under MIT License. Please refer to license.txt for details] 5 ============================================================================ */ 6 7 #define UNITY_INCLUDE_SETUP_STUBS 8 #include "unity.h" 9 #include <stddef.h> 10 11 /* If omitted from header, declare overrideable prototypes here so they're ready for use */ 12 #ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION 13 void UNITY_OUTPUT_CHAR(int); 14 #endif 15 16 /* Helpful macros for us to use here in Assert functions */ 17 #define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; TEST_ABORT(); } 18 #define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; TEST_ABORT(); } 19 #define RETURN_IF_FAIL_OR_IGNORE if (Unity.CurrentTestFailed || Unity.CurrentTestIgnored) return 20 21 struct UNITY_STORAGE_T Unity; 22 23 #ifdef UNITY_OUTPUT_COLOR 24 static const char UnityStrOk[] = "\033[42mOK\033[00m"; 25 static const char UnityStrPass[] = "\033[42mPASS\033[00m"; 26 static const char UnityStrFail[] = "\033[41mFAIL\033[00m"; 27 static const char UnityStrIgnore[] = "\033[43mIGNORE\033[00m"; 28 #else 29 static const char UnityStrOk[] = "OK"; 30 static const char UnityStrPass[] = "PASS"; 31 static const char UnityStrFail[] = "FAIL"; 32 static const char UnityStrIgnore[] = "IGNORE"; 33 #endif 34 static const char UnityStrNull[] = "NULL"; 35 static const char UnityStrSpacer[] = ". "; 36 static const char UnityStrExpected[] = " Expected "; 37 static const char UnityStrWas[] = " Was "; 38 static const char UnityStrGt[] = " to be greater than "; 39 static const char UnityStrLt[] = " to be less than "; 40 static const char UnityStrOrEqual[] = "or equal to "; 41 static const char UnityStrElement[] = " Element "; 42 static const char UnityStrByte[] = " Byte "; 43 static const char UnityStrMemory[] = " Memory Mismatch."; 44 static const char UnityStrDelta[] = " Values Not Within Delta "; 45 static const char UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; 46 static const char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; 47 static const char UnityStrNullPointerForActual[] = " Actual pointer was NULL"; 48 #ifndef UNITY_EXCLUDE_FLOAT 49 static const char UnityStrNot[] = "Not "; 50 static const char UnityStrInf[] = "Infinity"; 51 static const char UnityStrNegInf[] = "Negative Infinity"; 52 static const char UnityStrNaN[] = "NaN"; 53 static const char UnityStrDet[] = "Determinate"; 54 static const char UnityStrInvalidFloatTrait[] = "Invalid Float Trait"; 55 #endif 56 const char UnityStrErrFloat[] = "Unity Floating Point Disabled"; 57 const char UnityStrErrDouble[] = "Unity Double Precision Disabled"; 58 const char UnityStrErr64[] = "Unity 64-bit Support Disabled"; 59 static const char UnityStrBreaker[] = "-----------------------"; 60 static const char UnityStrResultsTests[] = " Tests "; 61 static const char UnityStrResultsFailures[] = " Failures "; 62 static const char UnityStrResultsIgnored[] = " Ignored "; 63 static const char UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; 64 static const char UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; 65 66 /*----------------------------------------------- 67 * Pretty Printers & Test Result Output Handlers 68 *-----------------------------------------------*/ 69 70 void UnityPrint(const char* string) 71 { 72 const char* pch = string; 73 74 if (pch != NULL) 75 { 76 while (*pch) 77 { 78 /* printable characters plus CR & LF are printed */ 79 if ((*pch <= 126) && (*pch >= 32)) 80 { 81 UNITY_OUTPUT_CHAR(*pch); 82 } 83 /* write escaped carriage returns */ 84 else if (*pch == 13) 85 { 86 UNITY_OUTPUT_CHAR('\\'); 87 UNITY_OUTPUT_CHAR('r'); 88 } 89 /* write escaped line feeds */ 90 else if (*pch == 10) 91 { 92 UNITY_OUTPUT_CHAR('\\'); 93 UNITY_OUTPUT_CHAR('n'); 94 } 95 #ifdef UNITY_OUTPUT_COLOR 96 /* print ANSI escape code */ 97 else if (*pch == 27 && *(pch + 1) == '[') 98 { 99 while (*pch && *pch != 'm') 100 { 101 UNITY_OUTPUT_CHAR(*pch); 102 pch++; 103 } 104 UNITY_OUTPUT_CHAR('m'); 105 } 106 #endif 107 /* unprintable characters are shown as codes */ 108 else 109 { 110 UNITY_OUTPUT_CHAR('\\'); 111 UNITY_OUTPUT_CHAR('x'); 112 UnityPrintNumberHex((UNITY_UINT)*pch, 2); 113 } 114 pch++; 115 } 116 } 117 } 118 119 void UnityPrintLen(const char* string, const UNITY_UINT32 length) 120 { 121 const char* pch = string; 122 123 if (pch != NULL) 124 { 125 while (*pch && (UNITY_UINT32)(pch - string) < length) 126 { 127 /* printable characters plus CR & LF are printed */ 128 if ((*pch <= 126) && (*pch >= 32)) 129 { 130 UNITY_OUTPUT_CHAR(*pch); 131 } 132 /* write escaped carriage returns */ 133 else if (*pch == 13) 134 { 135 UNITY_OUTPUT_CHAR('\\'); 136 UNITY_OUTPUT_CHAR('r'); 137 } 138 /* write escaped line feeds */ 139 else if (*pch == 10) 140 { 141 UNITY_OUTPUT_CHAR('\\'); 142 UNITY_OUTPUT_CHAR('n'); 143 } 144 /* unprintable characters are shown as codes */ 145 else 146 { 147 UNITY_OUTPUT_CHAR('\\'); 148 UNITY_OUTPUT_CHAR('x'); 149 UnityPrintNumberHex((UNITY_UINT)*pch, 2); 150 } 151 pch++; 152 } 153 } 154 } 155 156 /*-----------------------------------------------*/ 157 void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style) 158 { 159 if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) 160 { 161 UnityPrintNumber(number); 162 } 163 else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) 164 { 165 UnityPrintNumberUnsigned((UNITY_UINT)number); 166 } 167 else 168 { 169 UNITY_OUTPUT_CHAR('0'); 170 UNITY_OUTPUT_CHAR('x'); 171 UnityPrintNumberHex((UNITY_UINT)number, (char)((style & 0xF) * 2)); 172 } 173 } 174 175 /*-----------------------------------------------*/ 176 void UnityPrintNumber(const UNITY_INT number_to_print) 177 { 178 UNITY_UINT number = (UNITY_UINT)number_to_print; 179 180 if (number_to_print < 0) 181 { 182 /* A negative number, including MIN negative */ 183 UNITY_OUTPUT_CHAR('-'); 184 number = (UNITY_UINT)(-number_to_print); 185 } 186 UnityPrintNumberUnsigned(number); 187 } 188 189 /*----------------------------------------------- 190 * basically do an itoa using as little ram as possible */ 191 void UnityPrintNumberUnsigned(const UNITY_UINT number) 192 { 193 UNITY_UINT divisor = 1; 194 195 /* figure out initial divisor */ 196 while (number / divisor > 9) 197 { 198 divisor *= 10; 199 } 200 201 /* now mod and print, then divide divisor */ 202 do 203 { 204 UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); 205 divisor /= 10; 206 } while (divisor > 0); 207 } 208 209 /*-----------------------------------------------*/ 210 void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print) 211 { 212 int nibble; 213 char nibbles = nibbles_to_print; 214 if ((unsigned)nibbles > (2 * sizeof(number))) 215 nibbles = 2 * sizeof(number); 216 217 while (nibbles > 0) 218 { 219 nibbles--; 220 nibble = (int)(number >> (nibbles * 4)) & 0x0F; 221 if (nibble <= 9) 222 { 223 UNITY_OUTPUT_CHAR((char)('0' + nibble)); 224 } 225 else 226 { 227 UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble)); 228 } 229 } 230 } 231 232 /*-----------------------------------------------*/ 233 void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number) 234 { 235 UNITY_UINT current_bit = (UNITY_UINT)1 << (UNITY_INT_WIDTH - 1); 236 UNITY_INT32 i; 237 238 for (i = 0; i < UNITY_INT_WIDTH; i++) 239 { 240 if (current_bit & mask) 241 { 242 if (current_bit & number) 243 { 244 UNITY_OUTPUT_CHAR('1'); 245 } 246 else 247 { 248 UNITY_OUTPUT_CHAR('0'); 249 } 250 } 251 else 252 { 253 UNITY_OUTPUT_CHAR('X'); 254 } 255 current_bit = current_bit >> 1; 256 } 257 } 258 259 /*-----------------------------------------------*/ 260 #ifndef UNITY_EXCLUDE_FLOAT_PRINT 261 /* This function prints a floating-point value in a format similar to 262 * printf("%.6g"). It can work with either single- or double-precision, 263 * but for simplicity, it prints only 6 significant digits in either case. 264 * Printing more than 6 digits accurately is hard (at least in the single- 265 * precision case) and isn't attempted here. */ 266 void UnityPrintFloat(const UNITY_DOUBLE input_number) 267 { 268 UNITY_DOUBLE number = input_number; 269 270 /* print minus sign (including for negative zero) */ 271 if (number < 0.0f || (number == 0.0f && 1.0f / number < 0.0f)) 272 { 273 UNITY_OUTPUT_CHAR('-'); 274 number = -number; 275 } 276 277 /* handle zero, NaN, and +/- infinity */ 278 if (number == 0.0f) UnityPrint("0"); 279 else if (isnan(number)) UnityPrint("nan"); 280 else if (isinf(number)) UnityPrint("inf"); 281 else 282 { 283 int exponent = 0; 284 int decimals, digits; 285 UNITY_INT32 n; 286 char buf[16]; 287 288 /* scale up or down by powers of 10 */ 289 while (number < 100000.0f / 1e6f) { number *= 1e6f; exponent -= 6; } 290 while (number < 100000.0f) { number *= 10.0f; exponent--; } 291 while (number > 1000000.0f * 1e6f) { number /= 1e6f; exponent += 6; } 292 while (number > 1000000.0f) { number /= 10.0f; exponent++; } 293 294 /* round to nearest integer */ 295 n = ((UNITY_INT32)(number + number) + 1) / 2; 296 if (n > 999999) 297 { 298 n = 100000; 299 exponent++; 300 } 301 302 /* determine where to place decimal point */ 303 decimals = (exponent <= 0 && exponent >= -9) ? -exponent : 5; 304 exponent += decimals; 305 306 /* truncate trailing zeroes after decimal point */ 307 while (decimals > 0 && n % 10 == 0) 308 { 309 n /= 10; 310 decimals--; 311 } 312 313 /* build up buffer in reverse order */ 314 digits = 0; 315 while (n != 0 || digits < decimals + 1) 316 { 317 buf[digits++] = (char)('0' + n % 10); 318 n /= 10; 319 } 320 while (digits > 0) 321 { 322 if(digits == decimals) UNITY_OUTPUT_CHAR('.'); 323 UNITY_OUTPUT_CHAR(buf[--digits]); 324 } 325 326 /* print exponent if needed */ 327 if (exponent != 0) 328 { 329 UNITY_OUTPUT_CHAR('e'); 330 331 if(exponent < 0) 332 { 333 UNITY_OUTPUT_CHAR('-'); 334 exponent = -exponent; 335 } 336 else 337 { 338 UNITY_OUTPUT_CHAR('+'); 339 } 340 341 digits = 0; 342 while (exponent != 0 || digits < 2) 343 { 344 buf[digits++] = (char)('0' + exponent % 10); 345 exponent /= 10; 346 } 347 while (digits > 0) 348 { 349 UNITY_OUTPUT_CHAR(buf[--digits]); 350 } 351 } 352 } 353 } 354 #endif /* ! UNITY_EXCLUDE_FLOAT_PRINT */ 355 356 /*-----------------------------------------------*/ 357 static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) 358 { 359 UnityPrint(file); 360 UNITY_OUTPUT_CHAR(':'); 361 UnityPrintNumber((UNITY_INT)line); 362 UNITY_OUTPUT_CHAR(':'); 363 UnityPrint(Unity.CurrentTestName); 364 UNITY_OUTPUT_CHAR(':'); 365 } 366 367 /*-----------------------------------------------*/ 368 static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line) 369 { 370 UnityTestResultsBegin(Unity.TestFile, line); 371 UnityPrint(UnityStrFail); 372 UNITY_OUTPUT_CHAR(':'); 373 } 374 375 /*-----------------------------------------------*/ 376 void UnityConcludeTest(void) 377 { 378 if (Unity.CurrentTestIgnored) 379 { 380 Unity.TestIgnores++; 381 } 382 else if (!Unity.CurrentTestFailed) 383 { 384 UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber); 385 UnityPrint(UnityStrPass); 386 } 387 else 388 { 389 Unity.TestFailures++; 390 } 391 392 Unity.CurrentTestFailed = 0; 393 Unity.CurrentTestIgnored = 0; 394 UNITY_PRINT_EOL(); 395 UNITY_FLUSH_CALL(); 396 } 397 398 /*-----------------------------------------------*/ 399 static void UnityAddMsgIfSpecified(const char* msg) 400 { 401 if (msg) 402 { 403 UnityPrint(UnityStrSpacer); 404 #ifndef UNITY_EXCLUDE_DETAILS 405 if (Unity.CurrentDetail1) 406 { 407 UnityPrint(UnityStrDetail1Name); 408 UnityPrint(Unity.CurrentDetail1); 409 if (Unity.CurrentDetail2) 410 { 411 UnityPrint(UnityStrDetail2Name); 412 UnityPrint(Unity.CurrentDetail2); 413 } 414 UnityPrint(UnityStrSpacer); 415 } 416 #endif 417 UnityPrint(msg); 418 } 419 } 420 421 /*-----------------------------------------------*/ 422 static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual) 423 { 424 UnityPrint(UnityStrExpected); 425 if (expected != NULL) 426 { 427 UNITY_OUTPUT_CHAR('\''); 428 UnityPrint(expected); 429 UNITY_OUTPUT_CHAR('\''); 430 } 431 else 432 { 433 UnityPrint(UnityStrNull); 434 } 435 UnityPrint(UnityStrWas); 436 if (actual != NULL) 437 { 438 UNITY_OUTPUT_CHAR('\''); 439 UnityPrint(actual); 440 UNITY_OUTPUT_CHAR('\''); 441 } 442 else 443 { 444 UnityPrint(UnityStrNull); 445 } 446 } 447 448 /*-----------------------------------------------*/ 449 static void UnityPrintExpectedAndActualStringsLen(const char* expected, 450 const char* actual, 451 const UNITY_UINT32 length) 452 { 453 UnityPrint(UnityStrExpected); 454 if (expected != NULL) 455 { 456 UNITY_OUTPUT_CHAR('\''); 457 UnityPrintLen(expected, length); 458 UNITY_OUTPUT_CHAR('\''); 459 } 460 else 461 { 462 UnityPrint(UnityStrNull); 463 } 464 UnityPrint(UnityStrWas); 465 if (actual != NULL) 466 { 467 UNITY_OUTPUT_CHAR('\''); 468 UnityPrintLen(actual, length); 469 UNITY_OUTPUT_CHAR('\''); 470 } 471 else 472 { 473 UnityPrint(UnityStrNull); 474 } 475 } 476 477 /*----------------------------------------------- 478 * Assertion & Control Helpers 479 *-----------------------------------------------*/ 480 481 static int UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected, 482 UNITY_INTERNAL_PTR actual, 483 const UNITY_LINE_TYPE lineNumber, 484 const char* msg) 485 { 486 if (expected == actual) return 0; /* Both are NULL or same pointer */ 487 488 /* print and return true if just expected is NULL */ 489 if (expected == NULL) 490 { 491 UnityTestResultsFailBegin(lineNumber); 492 UnityPrint(UnityStrNullPointerForExpected); 493 UnityAddMsgIfSpecified(msg); 494 return 1; 495 } 496 497 /* print and return true if just actual is NULL */ 498 if (actual == NULL) 499 { 500 UnityTestResultsFailBegin(lineNumber); 501 UnityPrint(UnityStrNullPointerForActual); 502 UnityAddMsgIfSpecified(msg); 503 return 1; 504 } 505 506 return 0; /* return false if neither is NULL */ 507 } 508 509 /*----------------------------------------------- 510 * Assertion Functions 511 *-----------------------------------------------*/ 512 513 void UnityAssertBits(const UNITY_INT mask, 514 const UNITY_INT expected, 515 const UNITY_INT actual, 516 const char* msg, 517 const UNITY_LINE_TYPE lineNumber) 518 { 519 RETURN_IF_FAIL_OR_IGNORE; 520 521 if ((mask & expected) != (mask & actual)) 522 { 523 UnityTestResultsFailBegin(lineNumber); 524 UnityPrint(UnityStrExpected); 525 UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)expected); 526 UnityPrint(UnityStrWas); 527 UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)actual); 528 UnityAddMsgIfSpecified(msg); 529 UNITY_FAIL_AND_BAIL; 530 } 531 } 532 533 /*-----------------------------------------------*/ 534 void UnityAssertEqualNumber(const UNITY_INT expected, 535 const UNITY_INT actual, 536 const char* msg, 537 const UNITY_LINE_TYPE lineNumber, 538 const UNITY_DISPLAY_STYLE_T style) 539 { 540 RETURN_IF_FAIL_OR_IGNORE; 541 542 if (expected != actual) 543 { 544 UnityTestResultsFailBegin(lineNumber); 545 UnityPrint(UnityStrExpected); 546 UnityPrintNumberByStyle(expected, style); 547 UnityPrint(UnityStrWas); 548 UnityPrintNumberByStyle(actual, style); 549 UnityAddMsgIfSpecified(msg); 550 UNITY_FAIL_AND_BAIL; 551 } 552 } 553 554 /*-----------------------------------------------*/ 555 void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold, 556 const UNITY_INT actual, 557 const UNITY_COMPARISON_T compare, 558 const char *msg, 559 const UNITY_LINE_TYPE lineNumber, 560 const UNITY_DISPLAY_STYLE_T style) 561 { 562 int failed = 0; 563 RETURN_IF_FAIL_OR_IGNORE; 564 565 if (threshold == actual && compare & UNITY_EQUAL_TO) return; 566 if (threshold == actual) failed = 1; 567 568 if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) 569 { 570 if (actual > threshold && compare & UNITY_SMALLER_THAN) failed = 1; 571 if (actual < threshold && compare & UNITY_GREATER_THAN) failed = 1; 572 } 573 else /* UINT or HEX */ 574 { 575 if ((UNITY_UINT)actual > (UNITY_UINT)threshold && compare & UNITY_SMALLER_THAN) failed = 1; 576 if ((UNITY_UINT)actual < (UNITY_UINT)threshold && compare & UNITY_GREATER_THAN) failed = 1; 577 } 578 579 if (failed) 580 { 581 UnityTestResultsFailBegin(lineNumber); 582 UnityPrint(UnityStrExpected); 583 UnityPrintNumberByStyle(actual, style); 584 if (compare & UNITY_GREATER_THAN) UnityPrint(UnityStrGt); 585 if (compare & UNITY_SMALLER_THAN) UnityPrint(UnityStrLt); 586 if (compare & UNITY_EQUAL_TO) UnityPrint(UnityStrOrEqual); 587 UnityPrintNumberByStyle(threshold, style); 588 UnityAddMsgIfSpecified(msg); 589 UNITY_FAIL_AND_BAIL; 590 } 591 } 592 593 #define UnityPrintPointlessAndBail() \ 594 { \ 595 UnityTestResultsFailBegin(lineNumber); \ 596 UnityPrint(UnityStrPointless); \ 597 UnityAddMsgIfSpecified(msg); \ 598 UNITY_FAIL_AND_BAIL; } 599 600 /*-----------------------------------------------*/ 601 void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, 602 UNITY_INTERNAL_PTR actual, 603 const UNITY_UINT32 num_elements, 604 const char* msg, 605 const UNITY_LINE_TYPE lineNumber, 606 const UNITY_DISPLAY_STYLE_T style, 607 const UNITY_FLAGS_T flags) 608 { 609 UNITY_UINT32 elements = num_elements; 610 unsigned int length = style & 0xF; 611 612 RETURN_IF_FAIL_OR_IGNORE; 613 614 if (num_elements == 0) 615 { 616 UnityPrintPointlessAndBail(); 617 } 618 619 if (expected == actual) return; /* Both are NULL or same pointer */ 620 if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) 621 UNITY_FAIL_AND_BAIL; 622 623 while (elements--) 624 { 625 UNITY_INT expect_val; 626 UNITY_INT actual_val; 627 switch (length) 628 { 629 case 1: 630 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected; 631 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual; 632 break; 633 case 2: 634 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected; 635 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual; 636 break; 637 #ifdef UNITY_SUPPORT_64 638 case 8: 639 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected; 640 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual; 641 break; 642 #endif 643 default: /* length 4 bytes */ 644 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected; 645 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual; 646 length = 4; 647 break; 648 } 649 650 if (expect_val != actual_val) 651 { 652 if (style & UNITY_DISPLAY_RANGE_UINT && length < sizeof(expect_val)) 653 { /* For UINT, remove sign extension (padding 1's) from signed type casts above */ 654 UNITY_INT mask = 1; 655 mask = (mask << 8 * length) - 1; 656 expect_val &= mask; 657 actual_val &= mask; 658 } 659 UnityTestResultsFailBegin(lineNumber); 660 UnityPrint(UnityStrElement); 661 UnityPrintNumberUnsigned(num_elements - elements - 1); 662 UnityPrint(UnityStrExpected); 663 UnityPrintNumberByStyle(expect_val, style); 664 UnityPrint(UnityStrWas); 665 UnityPrintNumberByStyle(actual_val, style); 666 UnityAddMsgIfSpecified(msg); 667 UNITY_FAIL_AND_BAIL; 668 } 669 if (flags == UNITY_ARRAY_TO_ARRAY) 670 { 671 expected = (UNITY_INTERNAL_PTR)(length + (const char*)expected); 672 } 673 actual = (UNITY_INTERNAL_PTR)(length + (const char*)actual); 674 } 675 } 676 677 /*-----------------------------------------------*/ 678 #ifndef UNITY_EXCLUDE_FLOAT 679 /* Wrap this define in a function with variable types as float or double */ 680 #define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff) \ 681 if (isinf(expected) && isinf(actual) && ((expected < 0) == (actual < 0))) return 1; \ 682 if (UNITY_NAN_CHECK) return 1; \ 683 diff = actual - expected; \ 684 if (diff < 0) diff = -diff; \ 685 if (delta < 0) delta = -delta; \ 686 return !(isnan(diff) || isinf(diff) || (diff > delta)) 687 /* This first part of this condition will catch any NaN or Infinite values */ 688 #ifndef UNITY_NAN_NOT_EQUAL_NAN 689 #define UNITY_NAN_CHECK isnan(expected) && isnan(actual) 690 #else 691 #define UNITY_NAN_CHECK 0 692 #endif 693 694 #ifndef UNITY_EXCLUDE_FLOAT_PRINT 695 #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \ 696 { \ 697 UnityPrint(UnityStrExpected); \ 698 UnityPrintFloat(expected); \ 699 UnityPrint(UnityStrWas); \ 700 UnityPrintFloat(actual); } 701 #else 702 #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \ 703 UnityPrint(UnityStrDelta) 704 #endif /* UNITY_EXCLUDE_FLOAT_PRINT */ 705 706 static int UnityFloatsWithin(UNITY_FLOAT delta, UNITY_FLOAT expected, UNITY_FLOAT actual) 707 { 708 UNITY_FLOAT diff; 709 UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); 710 } 711 712 void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected, 713 UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual, 714 const UNITY_UINT32 num_elements, 715 const char* msg, 716 const UNITY_LINE_TYPE lineNumber, 717 const UNITY_FLAGS_T flags) 718 { 719 UNITY_UINT32 elements = num_elements; 720 UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_expected = expected; 721 UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_actual = actual; 722 723 RETURN_IF_FAIL_OR_IGNORE; 724 725 if (elements == 0) 726 { 727 UnityPrintPointlessAndBail(); 728 } 729 730 if (expected == actual) return; /* Both are NULL or same pointer */ 731 if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) 732 UNITY_FAIL_AND_BAIL; 733 734 while (elements--) 735 { 736 if (!UnityFloatsWithin(*ptr_expected * UNITY_FLOAT_PRECISION, *ptr_expected, *ptr_actual)) 737 { 738 UnityTestResultsFailBegin(lineNumber); 739 UnityPrint(UnityStrElement); 740 UnityPrintNumberUnsigned(num_elements - elements - 1); 741 UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)*ptr_expected, (UNITY_DOUBLE)*ptr_actual); 742 UnityAddMsgIfSpecified(msg); 743 UNITY_FAIL_AND_BAIL; 744 } 745 if (flags == UNITY_ARRAY_TO_ARRAY) 746 { 747 ptr_expected++; 748 } 749 ptr_actual++; 750 } 751 } 752 753 /*-----------------------------------------------*/ 754 void UnityAssertFloatsWithin(const UNITY_FLOAT delta, 755 const UNITY_FLOAT expected, 756 const UNITY_FLOAT actual, 757 const char* msg, 758 const UNITY_LINE_TYPE lineNumber) 759 { 760 RETURN_IF_FAIL_OR_IGNORE; 761 762 763 if (!UnityFloatsWithin(delta, expected, actual)) 764 { 765 UnityTestResultsFailBegin(lineNumber); 766 UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual); 767 UnityAddMsgIfSpecified(msg); 768 UNITY_FAIL_AND_BAIL; 769 } 770 } 771 772 /*-----------------------------------------------*/ 773 void UnityAssertFloatSpecial(const UNITY_FLOAT actual, 774 const char* msg, 775 const UNITY_LINE_TYPE lineNumber, 776 const UNITY_FLOAT_TRAIT_T style) 777 { 778 const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet}; 779 UNITY_INT should_be_trait = ((UNITY_INT)style & 1); 780 UNITY_INT is_trait = !should_be_trait; 781 UNITY_INT trait_index = (UNITY_INT)(style >> 1); 782 783 RETURN_IF_FAIL_OR_IGNORE; 784 785 switch (style) 786 { 787 case UNITY_FLOAT_IS_INF: 788 case UNITY_FLOAT_IS_NOT_INF: 789 is_trait = isinf(actual) && (actual > 0); 790 break; 791 case UNITY_FLOAT_IS_NEG_INF: 792 case UNITY_FLOAT_IS_NOT_NEG_INF: 793 is_trait = isinf(actual) && (actual < 0); 794 break; 795 796 case UNITY_FLOAT_IS_NAN: 797 case UNITY_FLOAT_IS_NOT_NAN: 798 is_trait = isnan(actual) ? 1 : 0; 799 break; 800 801 case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */ 802 case UNITY_FLOAT_IS_NOT_DET: 803 is_trait = !isinf(actual) && !isnan(actual); 804 break; 805 806 default: 807 trait_index = 0; 808 trait_names[0] = UnityStrInvalidFloatTrait; 809 break; 810 } 811 812 if (is_trait != should_be_trait) 813 { 814 UnityTestResultsFailBegin(lineNumber); 815 UnityPrint(UnityStrExpected); 816 if (!should_be_trait) 817 UnityPrint(UnityStrNot); 818 UnityPrint(trait_names[trait_index]); 819 UnityPrint(UnityStrWas); 820 #ifndef UNITY_EXCLUDE_FLOAT_PRINT 821 UnityPrintFloat((UNITY_DOUBLE)actual); 822 #else 823 if (should_be_trait) 824 UnityPrint(UnityStrNot); 825 UnityPrint(trait_names[trait_index]); 826 #endif 827 UnityAddMsgIfSpecified(msg); 828 UNITY_FAIL_AND_BAIL; 829 } 830 } 831 832 #endif /* not UNITY_EXCLUDE_FLOAT */ 833 834 /*-----------------------------------------------*/ 835 #ifndef UNITY_EXCLUDE_DOUBLE 836 static int UnityDoublesWithin(UNITY_DOUBLE delta, UNITY_DOUBLE expected, UNITY_DOUBLE actual) 837 { 838 UNITY_DOUBLE diff; 839 UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); 840 } 841 842 void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected, 843 UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual, 844 const UNITY_UINT32 num_elements, 845 const char* msg, 846 const UNITY_LINE_TYPE lineNumber, 847 const UNITY_FLAGS_T flags) 848 { 849 UNITY_UINT32 elements = num_elements; 850 UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_expected = expected; 851 UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_actual = actual; 852 853 RETURN_IF_FAIL_OR_IGNORE; 854 855 if (elements == 0) 856 { 857 UnityPrintPointlessAndBail(); 858 } 859 860 if (expected == actual) return; /* Both are NULL or same pointer */ 861 if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) 862 UNITY_FAIL_AND_BAIL; 863 864 while (elements--) 865 { 866 if (!UnityDoublesWithin(*ptr_expected * UNITY_DOUBLE_PRECISION, *ptr_expected, *ptr_actual)) 867 { 868 UnityTestResultsFailBegin(lineNumber); 869 UnityPrint(UnityStrElement); 870 UnityPrintNumberUnsigned(num_elements - elements - 1); 871 UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(*ptr_expected, *ptr_actual); 872 UnityAddMsgIfSpecified(msg); 873 UNITY_FAIL_AND_BAIL; 874 } 875 if (flags == UNITY_ARRAY_TO_ARRAY) 876 { 877 ptr_expected++; 878 } 879 ptr_actual++; 880 } 881 } 882 883 /*-----------------------------------------------*/ 884 void UnityAssertDoublesWithin(const UNITY_DOUBLE delta, 885 const UNITY_DOUBLE expected, 886 const UNITY_DOUBLE actual, 887 const char* msg, 888 const UNITY_LINE_TYPE lineNumber) 889 { 890 RETURN_IF_FAIL_OR_IGNORE; 891 892 if (!UnityDoublesWithin(delta, expected, actual)) 893 { 894 UnityTestResultsFailBegin(lineNumber); 895 UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual); 896 UnityAddMsgIfSpecified(msg); 897 UNITY_FAIL_AND_BAIL; 898 } 899 } 900 901 /*-----------------------------------------------*/ 902 903 void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual, 904 const char* msg, 905 const UNITY_LINE_TYPE lineNumber, 906 const UNITY_FLOAT_TRAIT_T style) 907 { 908 const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet}; 909 UNITY_INT should_be_trait = ((UNITY_INT)style & 1); 910 UNITY_INT is_trait = !should_be_trait; 911 UNITY_INT trait_index = (UNITY_INT)(style >> 1); 912 913 RETURN_IF_FAIL_OR_IGNORE; 914 915 switch (style) 916 { 917 case UNITY_FLOAT_IS_INF: 918 case UNITY_FLOAT_IS_NOT_INF: 919 is_trait = isinf(actual) && (actual > 0); 920 break; 921 case UNITY_FLOAT_IS_NEG_INF: 922 case UNITY_FLOAT_IS_NOT_NEG_INF: 923 is_trait = isinf(actual) && (actual < 0); 924 break; 925 926 case UNITY_FLOAT_IS_NAN: 927 case UNITY_FLOAT_IS_NOT_NAN: 928 is_trait = isnan(actual) ? 1 : 0; 929 break; 930 931 case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */ 932 case UNITY_FLOAT_IS_NOT_DET: 933 is_trait = !isinf(actual) && !isnan(actual); 934 break; 935 936 default: 937 trait_index = 0; 938 trait_names[0] = UnityStrInvalidFloatTrait; 939 break; 940 } 941 942 if (is_trait != should_be_trait) 943 { 944 UnityTestResultsFailBegin(lineNumber); 945 UnityPrint(UnityStrExpected); 946 if (!should_be_trait) 947 UnityPrint(UnityStrNot); 948 UnityPrint(trait_names[trait_index]); 949 UnityPrint(UnityStrWas); 950 #ifndef UNITY_EXCLUDE_FLOAT_PRINT 951 UnityPrintFloat(actual); 952 #else 953 if (should_be_trait) 954 UnityPrint(UnityStrNot); 955 UnityPrint(trait_names[trait_index]); 956 #endif 957 UnityAddMsgIfSpecified(msg); 958 UNITY_FAIL_AND_BAIL; 959 } 960 } 961 962 #endif /* not UNITY_EXCLUDE_DOUBLE */ 963 964 /*-----------------------------------------------*/ 965 void UnityAssertNumbersWithin(const UNITY_UINT delta, 966 const UNITY_INT expected, 967 const UNITY_INT actual, 968 const char* msg, 969 const UNITY_LINE_TYPE lineNumber, 970 const UNITY_DISPLAY_STYLE_T style) 971 { 972 RETURN_IF_FAIL_OR_IGNORE; 973 974 if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) 975 { 976 if (actual > expected) 977 Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(actual - expected) > delta); 978 else 979 Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(expected - actual) > delta); 980 } 981 else 982 { 983 if ((UNITY_UINT)actual > (UNITY_UINT)expected) 984 Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(actual - expected) > delta); 985 else 986 Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(expected - actual) > delta); 987 } 988 989 if (Unity.CurrentTestFailed) 990 { 991 UnityTestResultsFailBegin(lineNumber); 992 UnityPrint(UnityStrDelta); 993 UnityPrintNumberByStyle((UNITY_INT)delta, style); 994 UnityPrint(UnityStrExpected); 995 UnityPrintNumberByStyle(expected, style); 996 UnityPrint(UnityStrWas); 997 UnityPrintNumberByStyle(actual, style); 998 UnityAddMsgIfSpecified(msg); 999 UNITY_FAIL_AND_BAIL; 1000 } 1001 } 1002 1003 /*-----------------------------------------------*/ 1004 void UnityAssertEqualString(const char* expected, 1005 const char* actual, 1006 const char* msg, 1007 const UNITY_LINE_TYPE lineNumber) 1008 { 1009 UNITY_UINT32 i; 1010 1011 RETURN_IF_FAIL_OR_IGNORE; 1012 1013 /* if both pointers not null compare the strings */ 1014 if (expected && actual) 1015 { 1016 for (i = 0; expected[i] || actual[i]; i++) 1017 { 1018 if (expected[i] != actual[i]) 1019 { 1020 Unity.CurrentTestFailed = 1; 1021 break; 1022 } 1023 } 1024 } 1025 else 1026 { /* handle case of one pointers being null (if both null, test should pass) */ 1027 if (expected != actual) 1028 { 1029 Unity.CurrentTestFailed = 1; 1030 } 1031 } 1032 1033 if (Unity.CurrentTestFailed) 1034 { 1035 UnityTestResultsFailBegin(lineNumber); 1036 UnityPrintExpectedAndActualStrings(expected, actual); 1037 UnityAddMsgIfSpecified(msg); 1038 UNITY_FAIL_AND_BAIL; 1039 } 1040 } 1041 1042 /*-----------------------------------------------*/ 1043 void UnityAssertEqualStringLen(const char* expected, 1044 const char* actual, 1045 const UNITY_UINT32 length, 1046 const char* msg, 1047 const UNITY_LINE_TYPE lineNumber) 1048 { 1049 UNITY_UINT32 i; 1050 1051 RETURN_IF_FAIL_OR_IGNORE; 1052 1053 /* if both pointers not null compare the strings */ 1054 if (expected && actual) 1055 { 1056 for (i = 0; (i < length) && (expected[i] || actual[i]); i++) 1057 { 1058 if (expected[i] != actual[i]) 1059 { 1060 Unity.CurrentTestFailed = 1; 1061 break; 1062 } 1063 } 1064 } 1065 else 1066 { /* handle case of one pointers being null (if both null, test should pass) */ 1067 if (expected != actual) 1068 { 1069 Unity.CurrentTestFailed = 1; 1070 } 1071 } 1072 1073 if (Unity.CurrentTestFailed) 1074 { 1075 UnityTestResultsFailBegin(lineNumber); 1076 UnityPrintExpectedAndActualStringsLen(expected, actual, length); 1077 UnityAddMsgIfSpecified(msg); 1078 UNITY_FAIL_AND_BAIL; 1079 } 1080 } 1081 1082 /*-----------------------------------------------*/ 1083 void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected, 1084 const char** actual, 1085 const UNITY_UINT32 num_elements, 1086 const char* msg, 1087 const UNITY_LINE_TYPE lineNumber, 1088 const UNITY_FLAGS_T flags) 1089 { 1090 UNITY_UINT32 i = 0; 1091 UNITY_UINT32 j = 0; 1092 const char* expd = NULL; 1093 const char* act = NULL; 1094 1095 RETURN_IF_FAIL_OR_IGNORE; 1096 1097 /* if no elements, it's an error */ 1098 if (num_elements == 0) 1099 { 1100 UnityPrintPointlessAndBail(); 1101 } 1102 1103 if ((const void*)expected == (const void*)actual) 1104 { 1105 return; /* Both are NULL or same pointer */ 1106 } 1107 1108 if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) 1109 { 1110 UNITY_FAIL_AND_BAIL; 1111 } 1112 1113 if (flags != UNITY_ARRAY_TO_ARRAY) 1114 { 1115 expd = (const char*)expected; 1116 } 1117 1118 do 1119 { 1120 act = actual[j]; 1121 if (flags == UNITY_ARRAY_TO_ARRAY) 1122 { 1123 expd = ((const char* const*)expected)[j]; 1124 } 1125 1126 /* if both pointers not null compare the strings */ 1127 if (expd && act) 1128 { 1129 for (i = 0; expd[i] || act[i]; i++) 1130 { 1131 if (expd[i] != act[i]) 1132 { 1133 Unity.CurrentTestFailed = 1; 1134 break; 1135 } 1136 } 1137 } 1138 else 1139 { /* handle case of one pointers being null (if both null, test should pass) */ 1140 if (expd != act) 1141 { 1142 Unity.CurrentTestFailed = 1; 1143 } 1144 } 1145 1146 if (Unity.CurrentTestFailed) 1147 { 1148 UnityTestResultsFailBegin(lineNumber); 1149 if (num_elements > 1) 1150 { 1151 UnityPrint(UnityStrElement); 1152 UnityPrintNumberUnsigned(j); 1153 } 1154 UnityPrintExpectedAndActualStrings(expd, act); 1155 UnityAddMsgIfSpecified(msg); 1156 UNITY_FAIL_AND_BAIL; 1157 } 1158 } while (++j < num_elements); 1159 } 1160 1161 /*-----------------------------------------------*/ 1162 void UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected, 1163 UNITY_INTERNAL_PTR actual, 1164 const UNITY_UINT32 length, 1165 const UNITY_UINT32 num_elements, 1166 const char* msg, 1167 const UNITY_LINE_TYPE lineNumber, 1168 const UNITY_FLAGS_T flags) 1169 { 1170 UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; 1171 UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual; 1172 UNITY_UINT32 elements = num_elements; 1173 UNITY_UINT32 bytes; 1174 1175 RETURN_IF_FAIL_OR_IGNORE; 1176 1177 if ((elements == 0) || (length == 0)) 1178 { 1179 UnityPrintPointlessAndBail(); 1180 } 1181 1182 if (expected == actual) return; /* Both are NULL or same pointer */ 1183 if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) 1184 UNITY_FAIL_AND_BAIL; 1185 1186 while (elements--) 1187 { 1188 bytes = length; 1189 while (bytes--) 1190 { 1191 if (*ptr_exp != *ptr_act) 1192 { 1193 UnityTestResultsFailBegin(lineNumber); 1194 UnityPrint(UnityStrMemory); 1195 if (num_elements > 1) 1196 { 1197 UnityPrint(UnityStrElement); 1198 UnityPrintNumberUnsigned(num_elements - elements - 1); 1199 } 1200 UnityPrint(UnityStrByte); 1201 UnityPrintNumberUnsigned(length - bytes - 1); 1202 UnityPrint(UnityStrExpected); 1203 UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8); 1204 UnityPrint(UnityStrWas); 1205 UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8); 1206 UnityAddMsgIfSpecified(msg); 1207 UNITY_FAIL_AND_BAIL; 1208 } 1209 ptr_exp++; 1210 ptr_act++; 1211 } 1212 if (flags == UNITY_ARRAY_TO_VAL) 1213 { 1214 ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; 1215 } 1216 } 1217 } 1218 1219 /*-----------------------------------------------*/ 1220 1221 static union 1222 { 1223 UNITY_INT8 i8; 1224 UNITY_INT16 i16; 1225 UNITY_INT32 i32; 1226 #ifdef UNITY_SUPPORT_64 1227 UNITY_INT64 i64; 1228 #endif 1229 #ifndef UNITY_EXCLUDE_FLOAT 1230 float f; 1231 #endif 1232 #ifndef UNITY_EXCLUDE_DOUBLE 1233 double d; 1234 #endif 1235 } UnityQuickCompare; 1236 1237 UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size) 1238 { 1239 switch(size) 1240 { 1241 case 1: 1242 UnityQuickCompare.i8 = (UNITY_INT8)num; 1243 return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i8); 1244 1245 case 2: 1246 UnityQuickCompare.i16 = (UNITY_INT16)num; 1247 return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i16); 1248 1249 #ifdef UNITY_SUPPORT_64 1250 case 8: 1251 UnityQuickCompare.i64 = (UNITY_INT64)num; 1252 return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i64); 1253 #endif 1254 default: /* 4 bytes */ 1255 UnityQuickCompare.i32 = (UNITY_INT32)num; 1256 return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i32); 1257 } 1258 } 1259 1260 #ifndef UNITY_EXCLUDE_FLOAT 1261 UNITY_INTERNAL_PTR UnityFloatToPtr(const float num) 1262 { 1263 UnityQuickCompare.f = num; 1264 return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.f); 1265 } 1266 #endif 1267 1268 #ifndef UNITY_EXCLUDE_DOUBLE 1269 UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num) 1270 { 1271 UnityQuickCompare.d = num; 1272 return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.d); 1273 } 1274 #endif 1275 1276 /*----------------------------------------------- 1277 * Control Functions 1278 *-----------------------------------------------*/ 1279 1280 void UnityFail(const char* msg, const UNITY_LINE_TYPE line) 1281 { 1282 RETURN_IF_FAIL_OR_IGNORE; 1283 1284 UnityTestResultsBegin(Unity.TestFile, line); 1285 UnityPrint(UnityStrFail); 1286 if (msg != NULL) 1287 { 1288 UNITY_OUTPUT_CHAR(':'); 1289 1290 #ifndef UNITY_EXCLUDE_DETAILS 1291 if (Unity.CurrentDetail1) 1292 { 1293 UnityPrint(UnityStrDetail1Name); 1294 UnityPrint(Unity.CurrentDetail1); 1295 if (Unity.CurrentDetail2) 1296 { 1297 UnityPrint(UnityStrDetail2Name); 1298 UnityPrint(Unity.CurrentDetail2); 1299 } 1300 UnityPrint(UnityStrSpacer); 1301 } 1302 #endif 1303 if (msg[0] != ' ') 1304 { 1305 UNITY_OUTPUT_CHAR(' '); 1306 } 1307 UnityPrint(msg); 1308 } 1309 1310 UNITY_FAIL_AND_BAIL; 1311 } 1312 1313 /*-----------------------------------------------*/ 1314 void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) 1315 { 1316 RETURN_IF_FAIL_OR_IGNORE; 1317 1318 UnityTestResultsBegin(Unity.TestFile, line); 1319 UnityPrint(UnityStrIgnore); 1320 if (msg != NULL) 1321 { 1322 UNITY_OUTPUT_CHAR(':'); 1323 UNITY_OUTPUT_CHAR(' '); 1324 UnityPrint(msg); 1325 } 1326 UNITY_IGNORE_AND_BAIL; 1327 } 1328 1329 /*-----------------------------------------------*/ 1330 void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) 1331 { 1332 Unity.CurrentTestName = FuncName; 1333 Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; 1334 Unity.NumberOfTests++; 1335 UNITY_CLR_DETAILS(); 1336 if (TEST_PROTECT()) 1337 { 1338 setUp(); 1339 Func(); 1340 } 1341 if (TEST_PROTECT()) 1342 { 1343 tearDown(); 1344 } 1345 UnityConcludeTest(); 1346 } 1347 1348 /*-----------------------------------------------*/ 1349 void UnityBegin(const char* filename) 1350 { 1351 Unity.TestFile = filename; 1352 Unity.CurrentTestName = NULL; 1353 Unity.CurrentTestLineNumber = 0; 1354 Unity.NumberOfTests = 0; 1355 Unity.TestFailures = 0; 1356 Unity.TestIgnores = 0; 1357 Unity.CurrentTestFailed = 0; 1358 Unity.CurrentTestIgnored = 0; 1359 1360 UNITY_CLR_DETAILS(); 1361 UNITY_OUTPUT_START(); 1362 } 1363 1364 /*-----------------------------------------------*/ 1365 int UnityEnd(void) 1366 { 1367 UNITY_PRINT_EOL(); 1368 UnityPrint(UnityStrBreaker); 1369 UNITY_PRINT_EOL(); 1370 UnityPrintNumber((UNITY_INT)(Unity.NumberOfTests)); 1371 UnityPrint(UnityStrResultsTests); 1372 UnityPrintNumber((UNITY_INT)(Unity.TestFailures)); 1373 UnityPrint(UnityStrResultsFailures); 1374 UnityPrintNumber((UNITY_INT)(Unity.TestIgnores)); 1375 UnityPrint(UnityStrResultsIgnored); 1376 UNITY_PRINT_EOL(); 1377 if (Unity.TestFailures == 0U) 1378 { 1379 UnityPrint(UnityStrOk); 1380 } 1381 else 1382 { 1383 UnityPrint(UnityStrFail); 1384 #ifdef UNITY_DIFFERENTIATE_FINAL_FAIL 1385 UNITY_OUTPUT_CHAR('E'); UNITY_OUTPUT_CHAR('D'); 1386 #endif 1387 } 1388 UNITY_PRINT_EOL(); 1389 UNITY_FLUSH_CALL(); 1390 UNITY_OUTPUT_COMPLETE(); 1391 return (int)(Unity.TestFailures); 1392 } 1393 1394 /*----------------------------------------------- 1395 * Command Line Argument Support 1396 *-----------------------------------------------*/ 1397 #ifdef UNITY_USE_COMMAND_LINE_ARGS 1398 1399 char* UnityOptionIncludeNamed = NULL; 1400 char* UnityOptionExcludeNamed = NULL; 1401 int UnityVerbosity = 1; 1402 1403 int UnityParseOptions(int argc, char** argv) 1404 { 1405 UnityOptionIncludeNamed = NULL; 1406 UnityOptionExcludeNamed = NULL; 1407 1408 for (int i = 1; i < argc; i++) 1409 { 1410 if (argv[i][0] == '-') 1411 { 1412 switch (argv[i][1]) 1413 { 1414 case 'l': /* list tests */ 1415 return -1; 1416 case 'n': /* include tests with name including this string */ 1417 case 'f': /* an alias for -n */ 1418 if (argv[i][2] == '=') 1419 UnityOptionIncludeNamed = &argv[i][3]; 1420 else if (++i < argc) 1421 UnityOptionIncludeNamed = argv[i]; 1422 else 1423 { 1424 UnityPrint("ERROR: No Test String to Include Matches For"); 1425 UNITY_PRINT_EOL(); 1426 return 1; 1427 } 1428 break; 1429 case 'q': /* quiet */ 1430 UnityVerbosity = 0; 1431 break; 1432 case 'v': /* verbose */ 1433 UnityVerbosity = 2; 1434 break; 1435 case 'x': /* exclude tests with name including this string */ 1436 if (argv[i][2] == '=') 1437 UnityOptionExcludeNamed = &argv[i][3]; 1438 else if (++i < argc) 1439 UnityOptionExcludeNamed = argv[i]; 1440 else 1441 { 1442 UnityPrint("ERROR: No Test String to Exclude Matches For"); 1443 UNITY_PRINT_EOL(); 1444 return 1; 1445 } 1446 break; 1447 default: 1448 UnityPrint("ERROR: Unknown Option "); 1449 UNITY_OUTPUT_CHAR(argv[i][1]); 1450 UNITY_PRINT_EOL(); 1451 return 1; 1452 } 1453 } 1454 } 1455 1456 return 0; 1457 } 1458 1459 int IsStringInBiggerString(const char* longstring, const char* shortstring) 1460 { 1461 const char* lptr = longstring; 1462 const char* sptr = shortstring; 1463 const char* lnext = lptr; 1464 1465 if (*sptr == '*') 1466 return 1; 1467 1468 while (*lptr) 1469 { 1470 lnext = lptr + 1; 1471 1472 /* If they current bytes match, go on to the next bytes */ 1473 while (*lptr && *sptr && (*lptr == *sptr)) 1474 { 1475 lptr++; 1476 sptr++; 1477 1478 /* We're done if we match the entire string or up to a wildcard */ 1479 if (*sptr == '*') 1480 return 1; 1481 if (*sptr == ',') 1482 return 1; 1483 if (*sptr == '"') 1484 return 1; 1485 if (*sptr == '\'') 1486 return 1; 1487 if (*sptr == ':') 1488 return 2; 1489 if (*sptr == 0) 1490 return 1; 1491 } 1492 1493 /* Otherwise we start in the long pointer 1 character further and try again */ 1494 lptr = lnext; 1495 sptr = shortstring; 1496 } 1497 return 0; 1498 } 1499 1500 int UnityStringArgumentMatches(const char* str) 1501 { 1502 int retval; 1503 const char* ptr1; 1504 const char* ptr2; 1505 const char* ptrf; 1506 1507 /* Go through the options and get the substrings for matching one at a time */ 1508 ptr1 = str; 1509 while (ptr1[0] != 0) 1510 { 1511 if ((ptr1[0] == '"') || (ptr1[0] == '\'')) 1512 ptr1++; 1513 1514 /* look for the start of the next partial */ 1515 ptr2 = ptr1; 1516 ptrf = 0; 1517 do 1518 { 1519 ptr2++; 1520 if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')) 1521 ptrf = &ptr2[1]; 1522 } while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')); 1523 while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ','))) 1524 ptr2++; 1525 1526 /* done if complete filename match */ 1527 retval = IsStringInBiggerString(Unity.TestFile, ptr1); 1528 if (retval == 1) 1529 return retval; 1530 1531 /* done if testname match after filename partial match */ 1532 if ((retval == 2) && (ptrf != 0)) 1533 { 1534 if (IsStringInBiggerString(Unity.CurrentTestName, ptrf)) 1535 return 1; 1536 } 1537 1538 /* done if complete testname match */ 1539 if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1) 1540 return 1; 1541 1542 ptr1 = ptr2; 1543 } 1544 1545 /* we couldn't find a match for any substrings */ 1546 return 0; 1547 } 1548 1549 int UnityTestMatches(void) 1550 { 1551 /* Check if this test name matches the included test pattern */ 1552 int retval; 1553 if (UnityOptionIncludeNamed) 1554 { 1555 retval = UnityStringArgumentMatches(UnityOptionIncludeNamed); 1556 } 1557 else 1558 retval = 1; 1559 1560 /* Check if this test name matches the excluded test pattern */ 1561 if (UnityOptionExcludeNamed) 1562 { 1563 if (UnityStringArgumentMatches(UnityOptionExcludeNamed)) 1564 retval = 0; 1565 } 1566 return retval; 1567 } 1568 1569 #endif /* UNITY_USE_COMMAND_LINE_ARGS */ 1570 /*-----------------------------------------------*/