1 /* ========================================================================= 2 Unity Project - A Test Framework for C 3 Copyright (c) 2007-19 Mike Karlesky, Mark VanderVoord, Greg Williams 4 [Released under MIT License. Please refer to license.txt for details] 5 ============================================================================ */ 6 7 #include "unity.h" 8 #include <stddef.h> 9 10 #ifdef AVR 11 #include <avr/pgmspace.h> 12 #else 13 #define PROGMEM 14 #endif 15 16 /* If omitted from header, declare overrideable prototypes here so they're ready for use */ 17 #ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION 18 void UNITY_OUTPUT_CHAR(int); 19 #endif 20 21 /* Helpful macros for us to use here in Assert functions */ 22 #define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; UNITY_OUTPUT_FLUSH(); TEST_ABORT(); } 23 #define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; UNITY_OUTPUT_FLUSH(); TEST_ABORT(); } 24 #define RETURN_IF_FAIL_OR_IGNORE if (Unity.CurrentTestFailed || Unity.CurrentTestIgnored) return 25 26 struct UNITY_STORAGE_T Unity; 27 28 #ifdef UNITY_OUTPUT_COLOR 29 const char PROGMEM UnityStrOk[] = "\033[42mOK\033[00m"; 30 const char PROGMEM UnityStrPass[] = "\033[42mPASS\033[00m"; 31 const char PROGMEM UnityStrFail[] = "\033[41mFAIL\033[00m"; 32 const char PROGMEM UnityStrIgnore[] = "\033[43mIGNORE\033[00m"; 33 #else 34 const char PROGMEM UnityStrOk[] = "OK"; 35 const char PROGMEM UnityStrPass[] = "PASS"; 36 const char PROGMEM UnityStrFail[] = "FAIL"; 37 const char PROGMEM UnityStrIgnore[] = "IGNORE"; 38 #endif 39 static const char PROGMEM UnityStrNull[] = "NULL"; 40 static const char PROGMEM UnityStrSpacer[] = ". "; 41 static const char PROGMEM UnityStrExpected[] = " Expected "; 42 static const char PROGMEM UnityStrWas[] = " Was "; 43 static const char PROGMEM UnityStrGt[] = " to be greater than "; 44 static const char PROGMEM UnityStrLt[] = " to be less than "; 45 static const char PROGMEM UnityStrOrEqual[] = "or equal to "; 46 static const char PROGMEM UnityStrElement[] = " Element "; 47 static const char PROGMEM UnityStrByte[] = " Byte "; 48 static const char PROGMEM UnityStrMemory[] = " Memory Mismatch."; 49 static const char PROGMEM UnityStrDelta[] = " Values Not Within Delta "; 50 static const char PROGMEM UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; 51 static const char PROGMEM UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; 52 static const char PROGMEM UnityStrNullPointerForActual[] = " Actual pointer was NULL"; 53 #ifndef UNITY_EXCLUDE_FLOAT 54 static const char PROGMEM UnityStrNot[] = "Not "; 55 static const char PROGMEM UnityStrInf[] = "Infinity"; 56 static const char PROGMEM UnityStrNegInf[] = "Negative Infinity"; 57 static const char PROGMEM UnityStrNaN[] = "NaN"; 58 static const char PROGMEM UnityStrDet[] = "Determinate"; 59 static const char PROGMEM UnityStrInvalidFloatTrait[] = "Invalid Float Trait"; 60 #endif 61 const char PROGMEM UnityStrErrShorthand[] = "Unity Shorthand Support Disabled"; 62 const char PROGMEM UnityStrErrFloat[] = "Unity Floating Point Disabled"; 63 const char PROGMEM UnityStrErrDouble[] = "Unity Double Precision Disabled"; 64 const char PROGMEM UnityStrErr64[] = "Unity 64-bit Support Disabled"; 65 static const char PROGMEM UnityStrBreaker[] = "-----------------------"; 66 static const char PROGMEM UnityStrResultsTests[] = " Tests "; 67 static const char PROGMEM UnityStrResultsFailures[] = " Failures "; 68 static const char PROGMEM UnityStrResultsIgnored[] = " Ignored "; 69 static const char PROGMEM UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; 70 static const char PROGMEM UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; 71 72 /*----------------------------------------------- 73 * Pretty Printers & Test Result Output Handlers 74 *-----------------------------------------------*/ 75 76 /*-----------------------------------------------*/ 77 /* Local helper function to print characters. */ UnityPrintChar(const char * pch)78 static void UnityPrintChar(const char* pch) 79 { 80 /* printable characters plus CR & LF are printed */ 81 if ((*pch <= 126) && (*pch >= 32)) 82 { 83 UNITY_OUTPUT_CHAR(*pch); 84 } 85 /* write escaped carriage returns */ 86 else if (*pch == 13) 87 { 88 UNITY_OUTPUT_CHAR('\\'); 89 UNITY_OUTPUT_CHAR('r'); 90 } 91 /* write escaped line feeds */ 92 else if (*pch == 10) 93 { 94 UNITY_OUTPUT_CHAR('\\'); 95 UNITY_OUTPUT_CHAR('n'); 96 } 97 /* unprintable characters are shown as codes */ 98 else 99 { 100 UNITY_OUTPUT_CHAR('\\'); 101 UNITY_OUTPUT_CHAR('x'); 102 UnityPrintNumberHex((UNITY_UINT)*pch, 2); 103 } 104 } 105 106 /*-----------------------------------------------*/ 107 /* Local helper function to print ANSI escape strings e.g. "\033[42m". */ 108 #ifdef UNITY_OUTPUT_COLOR UnityPrintAnsiEscapeString(const char * string)109 static UNITY_UINT UnityPrintAnsiEscapeString(const char* string) 110 { 111 const char* pch = string; 112 UNITY_UINT count = 0; 113 114 while (*pch && (*pch != 'm')) 115 { 116 UNITY_OUTPUT_CHAR(*pch); 117 pch++; 118 count++; 119 } 120 UNITY_OUTPUT_CHAR('m'); 121 count++; 122 123 return count; 124 } 125 #endif 126 127 /*-----------------------------------------------*/ UnityPrint(const char * string)128 void UnityPrint(const char* string) 129 { 130 const char* pch = string; 131 132 if (pch != NULL) 133 { 134 while (*pch) 135 { 136 #ifdef UNITY_OUTPUT_COLOR 137 /* print ANSI escape code */ 138 if ((*pch == 27) && (*(pch + 1) == '[')) 139 { 140 pch += UnityPrintAnsiEscapeString(pch); 141 continue; 142 } 143 #endif 144 UnityPrintChar(pch); 145 pch++; 146 } 147 } 148 } 149 150 /*-----------------------------------------------*/ 151 #ifdef UNITY_INCLUDE_PRINT_FORMATTED UnityPrintFormatted(const char * format,...)152 void UnityPrintFormatted(const char* format, ...) 153 { 154 const char* pch = format; 155 va_list va; 156 va_start(va, format); 157 158 if (pch != NULL) 159 { 160 while (*pch) 161 { 162 /* format identification character */ 163 if (*pch == '%') 164 { 165 pch++; 166 167 if (pch != NULL) 168 { 169 switch (*pch) 170 { 171 case 'd': 172 case 'i': 173 { 174 const int number = va_arg(va, int); 175 UnityPrintNumber((UNITY_INT)number); 176 break; 177 } 178 #ifndef UNITY_EXCLUDE_FLOAT_PRINT 179 case 'f': 180 case 'g': 181 { 182 const double number = va_arg(va, double); 183 UnityPrintFloat((UNITY_DOUBLE)number); 184 break; 185 } 186 #endif 187 case 'u': 188 { 189 const unsigned int number = va_arg(va, unsigned int); 190 UnityPrintNumberUnsigned((UNITY_UINT)number); 191 break; 192 } 193 case 'b': 194 { 195 const unsigned int number = va_arg(va, unsigned int); 196 const UNITY_UINT mask = (UNITY_UINT)0 - (UNITY_UINT)1; 197 UNITY_OUTPUT_CHAR('0'); 198 UNITY_OUTPUT_CHAR('b'); 199 UnityPrintMask(mask, (UNITY_UINT)number); 200 break; 201 } 202 case 'x': 203 case 'X': 204 case 'p': 205 { 206 const unsigned int number = va_arg(va, unsigned int); 207 UNITY_OUTPUT_CHAR('0'); 208 UNITY_OUTPUT_CHAR('x'); 209 UnityPrintNumberHex((UNITY_UINT)number, 8); 210 break; 211 } 212 case 'c': 213 { 214 const int ch = va_arg(va, int); 215 UnityPrintChar((const char *)&ch); 216 break; 217 } 218 case 's': 219 { 220 const char * string = va_arg(va, const char *); 221 UnityPrint(string); 222 break; 223 } 224 case '%': 225 { 226 UnityPrintChar(pch); 227 break; 228 } 229 default: 230 { 231 /* print the unknown format character */ 232 UNITY_OUTPUT_CHAR('%'); 233 UnityPrintChar(pch); 234 break; 235 } 236 } 237 } 238 } 239 #ifdef UNITY_OUTPUT_COLOR 240 /* print ANSI escape code */ 241 else if ((*pch == 27) && (*(pch + 1) == '[')) 242 { 243 pch += UnityPrintAnsiEscapeString(pch); 244 continue; 245 } 246 #endif 247 else if (*pch == '\n') 248 { 249 UNITY_PRINT_EOL(); 250 } 251 else 252 { 253 UnityPrintChar(pch); 254 } 255 256 pch++; 257 } 258 } 259 260 va_end(va); 261 } 262 #endif /* ! UNITY_INCLUDE_PRINT_FORMATTED */ 263 264 /*-----------------------------------------------*/ UnityPrintLen(const char * string,const UNITY_UINT32 length)265 void UnityPrintLen(const char* string, const UNITY_UINT32 length) 266 { 267 const char* pch = string; 268 269 if (pch != NULL) 270 { 271 while (*pch && ((UNITY_UINT32)(pch - string) < length)) 272 { 273 /* printable characters plus CR & LF are printed */ 274 if ((*pch <= 126) && (*pch >= 32)) 275 { 276 UNITY_OUTPUT_CHAR(*pch); 277 } 278 /* write escaped carriage returns */ 279 else if (*pch == 13) 280 { 281 UNITY_OUTPUT_CHAR('\\'); 282 UNITY_OUTPUT_CHAR('r'); 283 } 284 /* write escaped line feeds */ 285 else if (*pch == 10) 286 { 287 UNITY_OUTPUT_CHAR('\\'); 288 UNITY_OUTPUT_CHAR('n'); 289 } 290 /* unprintable characters are shown as codes */ 291 else 292 { 293 UNITY_OUTPUT_CHAR('\\'); 294 UNITY_OUTPUT_CHAR('x'); 295 UnityPrintNumberHex((UNITY_UINT)*pch, 2); 296 } 297 pch++; 298 } 299 } 300 } 301 302 /*-----------------------------------------------*/ UnityPrintNumberByStyle(const UNITY_INT number,const UNITY_DISPLAY_STYLE_T style)303 void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style) 304 { 305 if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) 306 { 307 if (style == UNITY_DISPLAY_STYLE_CHAR) 308 { 309 /* printable characters plus CR & LF are printed */ 310 UNITY_OUTPUT_CHAR('\''); 311 if ((number <= 126) && (number >= 32)) 312 { 313 UNITY_OUTPUT_CHAR((int)number); 314 } 315 /* write escaped carriage returns */ 316 else if (number == 13) 317 { 318 UNITY_OUTPUT_CHAR('\\'); 319 UNITY_OUTPUT_CHAR('r'); 320 } 321 /* write escaped line feeds */ 322 else if (number == 10) 323 { 324 UNITY_OUTPUT_CHAR('\\'); 325 UNITY_OUTPUT_CHAR('n'); 326 } 327 /* unprintable characters are shown as codes */ 328 else 329 { 330 UNITY_OUTPUT_CHAR('\\'); 331 UNITY_OUTPUT_CHAR('x'); 332 UnityPrintNumberHex((UNITY_UINT)number, 2); 333 } 334 UNITY_OUTPUT_CHAR('\''); 335 } 336 else 337 { 338 UnityPrintNumber(number); 339 } 340 } 341 else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) 342 { 343 UnityPrintNumberUnsigned((UNITY_UINT)number); 344 } 345 else 346 { 347 UNITY_OUTPUT_CHAR('0'); 348 UNITY_OUTPUT_CHAR('x'); 349 UnityPrintNumberHex((UNITY_UINT)number, (char)((style & 0xF) * 2)); 350 } 351 } 352 353 /*-----------------------------------------------*/ UnityPrintNumber(const UNITY_INT number_to_print)354 void UnityPrintNumber(const UNITY_INT number_to_print) 355 { 356 UNITY_UINT number = (UNITY_UINT)number_to_print; 357 358 if (number_to_print < 0) 359 { 360 /* A negative number, including MIN negative */ 361 UNITY_OUTPUT_CHAR('-'); 362 number = (~number) + 1; 363 } 364 UnityPrintNumberUnsigned(number); 365 } 366 367 /*----------------------------------------------- 368 * basically do an itoa using as little ram as possible */ UnityPrintNumberUnsigned(const UNITY_UINT number)369 void UnityPrintNumberUnsigned(const UNITY_UINT number) 370 { 371 UNITY_UINT divisor = 1; 372 373 /* figure out initial divisor */ 374 while (number / divisor > 9) 375 { 376 divisor *= 10; 377 } 378 379 /* now mod and print, then divide divisor */ 380 do 381 { 382 UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); 383 divisor /= 10; 384 } while (divisor > 0); 385 } 386 387 /*-----------------------------------------------*/ UnityPrintNumberHex(const UNITY_UINT number,const char nibbles_to_print)388 void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print) 389 { 390 int nibble; 391 char nibbles = nibbles_to_print; 392 393 if ((unsigned)nibbles > UNITY_MAX_NIBBLES) 394 { 395 nibbles = UNITY_MAX_NIBBLES; 396 } 397 398 while (nibbles > 0) 399 { 400 nibbles--; 401 nibble = (int)(number >> (nibbles * 4)) & 0x0F; 402 if (nibble <= 9) 403 { 404 UNITY_OUTPUT_CHAR((char)('0' + nibble)); 405 } 406 else 407 { 408 UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble)); 409 } 410 } 411 } 412 413 /*-----------------------------------------------*/ UnityPrintMask(const UNITY_UINT mask,const UNITY_UINT number)414 void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number) 415 { 416 UNITY_UINT current_bit = (UNITY_UINT)1 << (UNITY_INT_WIDTH - 1); 417 UNITY_INT32 i; 418 419 for (i = 0; i < UNITY_INT_WIDTH; i++) 420 { 421 if (current_bit & mask) 422 { 423 if (current_bit & number) 424 { 425 UNITY_OUTPUT_CHAR('1'); 426 } 427 else 428 { 429 UNITY_OUTPUT_CHAR('0'); 430 } 431 } 432 else 433 { 434 UNITY_OUTPUT_CHAR('X'); 435 } 436 current_bit = current_bit >> 1; 437 } 438 } 439 440 /*-----------------------------------------------*/ 441 #ifndef UNITY_EXCLUDE_FLOAT_PRINT 442 /* 443 * This function prints a floating-point value in a format similar to 444 * printf("%.7g") on a single-precision machine or printf("%.9g") on a 445 * double-precision machine. The 7th digit won't always be totally correct 446 * in single-precision operation (for that level of accuracy, a more 447 * complicated algorithm would be needed). 448 */ UnityPrintFloat(const UNITY_DOUBLE input_number)449 void UnityPrintFloat(const UNITY_DOUBLE input_number) 450 { 451 #ifdef UNITY_INCLUDE_DOUBLE 452 static const int sig_digits = 9; 453 static const UNITY_INT32 min_scaled = 100000000; 454 static const UNITY_INT32 max_scaled = 1000000000; 455 #else 456 static const int sig_digits = 7; 457 static const UNITY_INT32 min_scaled = 1000000; 458 static const UNITY_INT32 max_scaled = 10000000; 459 #endif 460 461 UNITY_DOUBLE number = input_number; 462 463 /* print minus sign (does not handle negative zero) */ 464 if (number < 0.0f) 465 { 466 UNITY_OUTPUT_CHAR('-'); 467 number = -number; 468 } 469 470 /* handle zero, NaN, and +/- infinity */ 471 if (number == 0.0f) 472 { 473 UnityPrint("0"); 474 } 475 else if (isnan(number)) 476 { 477 UnityPrint("nan"); 478 } 479 else if (isinf(number)) 480 { 481 UnityPrint("inf"); 482 } 483 else 484 { 485 UNITY_INT32 n_int = 0, n; 486 int exponent = 0; 487 int decimals, digits; 488 char buf[16] = {0}; 489 490 /* 491 * Scale up or down by powers of 10. To minimize rounding error, 492 * start with a factor/divisor of 10^10, which is the largest 493 * power of 10 that can be represented exactly. Finally, compute 494 * (exactly) the remaining power of 10 and perform one more 495 * multiplication or division. 496 */ 497 if (number < 1.0f) 498 { 499 UNITY_DOUBLE factor = 1.0f; 500 501 while (number < (UNITY_DOUBLE)max_scaled / 1e10f) { number *= 1e10f; exponent -= 10; } 502 while (number * factor < (UNITY_DOUBLE)min_scaled) { factor *= 10.0f; exponent--; } 503 504 number *= factor; 505 } 506 else if (number > (UNITY_DOUBLE)max_scaled) 507 { 508 UNITY_DOUBLE divisor = 1.0f; 509 510 while (number > (UNITY_DOUBLE)min_scaled * 1e10f) { number /= 1e10f; exponent += 10; } 511 while (number / divisor > (UNITY_DOUBLE)max_scaled) { divisor *= 10.0f; exponent++; } 512 513 number /= divisor; 514 } 515 else 516 { 517 /* 518 * In this range, we can split off the integer part before 519 * doing any multiplications. This reduces rounding error by 520 * freeing up significant bits in the fractional part. 521 */ 522 UNITY_DOUBLE factor = 1.0f; 523 n_int = (UNITY_INT32)number; 524 number -= (UNITY_DOUBLE)n_int; 525 526 while (n_int < min_scaled) { n_int *= 10; factor *= 10.0f; exponent--; } 527 528 number *= factor; 529 } 530 531 /* round to nearest integer */ 532 n = ((UNITY_INT32)(number + number) + 1) / 2; 533 534 #ifndef UNITY_ROUND_TIES_AWAY_FROM_ZERO 535 /* round to even if exactly between two integers */ 536 if ((n & 1) && (((UNITY_DOUBLE)n - number) == 0.5f)) 537 n--; 538 #endif 539 540 n += n_int; 541 542 if (n >= max_scaled) 543 { 544 n = min_scaled; 545 exponent++; 546 } 547 548 /* determine where to place decimal point */ 549 decimals = ((exponent <= 0) && (exponent >= -(sig_digits + 3))) ? (-exponent) : (sig_digits - 1); 550 exponent += decimals; 551 552 /* truncate trailing zeroes after decimal point */ 553 while ((decimals > 0) && ((n % 10) == 0)) 554 { 555 n /= 10; 556 decimals--; 557 } 558 559 /* build up buffer in reverse order */ 560 digits = 0; 561 while ((n != 0) || (digits < (decimals + 1))) 562 { 563 buf[digits++] = (char)('0' + n % 10); 564 n /= 10; 565 } 566 while (digits > 0) 567 { 568 if (digits == decimals) { UNITY_OUTPUT_CHAR('.'); } 569 UNITY_OUTPUT_CHAR(buf[--digits]); 570 } 571 572 /* print exponent if needed */ 573 if (exponent != 0) 574 { 575 UNITY_OUTPUT_CHAR('e'); 576 577 if (exponent < 0) 578 { 579 UNITY_OUTPUT_CHAR('-'); 580 exponent = -exponent; 581 } 582 else 583 { 584 UNITY_OUTPUT_CHAR('+'); 585 } 586 587 digits = 0; 588 while ((exponent != 0) || (digits < 2)) 589 { 590 buf[digits++] = (char)('0' + exponent % 10); 591 exponent /= 10; 592 } 593 while (digits > 0) 594 { 595 UNITY_OUTPUT_CHAR(buf[--digits]); 596 } 597 } 598 } 599 } 600 #endif /* ! UNITY_EXCLUDE_FLOAT_PRINT */ 601 602 /*-----------------------------------------------*/ UnityTestResultsBegin(const char * file,const UNITY_LINE_TYPE line)603 static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) 604 { 605 #ifdef UNITY_OUTPUT_FOR_ECLIPSE 606 UNITY_OUTPUT_CHAR('('); 607 UnityPrint(file); 608 UNITY_OUTPUT_CHAR(':'); 609 UnityPrintNumber((UNITY_INT)line); 610 UNITY_OUTPUT_CHAR(')'); 611 UNITY_OUTPUT_CHAR(' '); 612 UnityPrint(Unity.CurrentTestName); 613 UNITY_OUTPUT_CHAR(':'); 614 #else 615 #ifdef UNITY_OUTPUT_FOR_IAR_WORKBENCH 616 UnityPrint("<SRCREF line="); 617 UnityPrintNumber((UNITY_INT)line); 618 UnityPrint(" file=\""); 619 UnityPrint(file); 620 UNITY_OUTPUT_CHAR('"'); 621 UNITY_OUTPUT_CHAR('>'); 622 UnityPrint(Unity.CurrentTestName); 623 UnityPrint("</SRCREF> "); 624 #else 625 #ifdef UNITY_OUTPUT_FOR_QT_CREATOR 626 UnityPrint("file://"); 627 UnityPrint(file); 628 UNITY_OUTPUT_CHAR(':'); 629 UnityPrintNumber((UNITY_INT)line); 630 UNITY_OUTPUT_CHAR(' '); 631 UnityPrint(Unity.CurrentTestName); 632 UNITY_OUTPUT_CHAR(':'); 633 #else 634 UnityPrint(file); 635 UNITY_OUTPUT_CHAR(':'); 636 UnityPrintNumber((UNITY_INT)line); 637 UNITY_OUTPUT_CHAR(':'); 638 UnityPrint(Unity.CurrentTestName); 639 UNITY_OUTPUT_CHAR(':'); 640 #endif 641 #endif 642 #endif 643 } 644 645 /*-----------------------------------------------*/ UnityTestResultsFailBegin(const UNITY_LINE_TYPE line)646 static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line) 647 { 648 UnityTestResultsBegin(Unity.TestFile, line); 649 UnityPrint(UnityStrFail); 650 UNITY_OUTPUT_CHAR(':'); 651 } 652 653 /*-----------------------------------------------*/ UnityConcludeTest(void)654 void UnityConcludeTest(void) 655 { 656 if (Unity.CurrentTestIgnored) 657 { 658 Unity.TestIgnores++; 659 } 660 else if (!Unity.CurrentTestFailed) 661 { 662 UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber); 663 UnityPrint(UnityStrPass); 664 } 665 else 666 { 667 Unity.TestFailures++; 668 } 669 670 Unity.CurrentTestFailed = 0; 671 Unity.CurrentTestIgnored = 0; 672 UNITY_PRINT_EXEC_TIME(); 673 UNITY_PRINT_EOL(); 674 UNITY_FLUSH_CALL(); 675 } 676 677 /*-----------------------------------------------*/ UnityAddMsgIfSpecified(const char * msg)678 static void UnityAddMsgIfSpecified(const char* msg) 679 { 680 if (msg) 681 { 682 UnityPrint(UnityStrSpacer); 683 #ifndef UNITY_EXCLUDE_DETAILS 684 if (Unity.CurrentDetail1) 685 { 686 UnityPrint(UnityStrDetail1Name); 687 UnityPrint(Unity.CurrentDetail1); 688 if (Unity.CurrentDetail2) 689 { 690 UnityPrint(UnityStrDetail2Name); 691 UnityPrint(Unity.CurrentDetail2); 692 } 693 UnityPrint(UnityStrSpacer); 694 } 695 #endif 696 UnityPrint(msg); 697 } 698 } 699 700 /*-----------------------------------------------*/ UnityPrintExpectedAndActualStrings(const char * expected,const char * actual)701 static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual) 702 { 703 UnityPrint(UnityStrExpected); 704 if (expected != NULL) 705 { 706 UNITY_OUTPUT_CHAR('\''); 707 UnityPrint(expected); 708 UNITY_OUTPUT_CHAR('\''); 709 } 710 else 711 { 712 UnityPrint(UnityStrNull); 713 } 714 UnityPrint(UnityStrWas); 715 if (actual != NULL) 716 { 717 UNITY_OUTPUT_CHAR('\''); 718 UnityPrint(actual); 719 UNITY_OUTPUT_CHAR('\''); 720 } 721 else 722 { 723 UnityPrint(UnityStrNull); 724 } 725 } 726 727 /*-----------------------------------------------*/ UnityPrintExpectedAndActualStringsLen(const char * expected,const char * actual,const UNITY_UINT32 length)728 static void UnityPrintExpectedAndActualStringsLen(const char* expected, 729 const char* actual, 730 const UNITY_UINT32 length) 731 { 732 UnityPrint(UnityStrExpected); 733 if (expected != NULL) 734 { 735 UNITY_OUTPUT_CHAR('\''); 736 UnityPrintLen(expected, length); 737 UNITY_OUTPUT_CHAR('\''); 738 } 739 else 740 { 741 UnityPrint(UnityStrNull); 742 } 743 UnityPrint(UnityStrWas); 744 if (actual != NULL) 745 { 746 UNITY_OUTPUT_CHAR('\''); 747 UnityPrintLen(actual, length); 748 UNITY_OUTPUT_CHAR('\''); 749 } 750 else 751 { 752 UnityPrint(UnityStrNull); 753 } 754 } 755 756 /*----------------------------------------------- 757 * Assertion & Control Helpers 758 *-----------------------------------------------*/ 759 760 /*-----------------------------------------------*/ UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected,UNITY_INTERNAL_PTR actual,const UNITY_LINE_TYPE lineNumber,const char * msg)761 static int UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected, 762 UNITY_INTERNAL_PTR actual, 763 const UNITY_LINE_TYPE lineNumber, 764 const char* msg) 765 { 766 /* Both are NULL or same pointer */ 767 if (expected == actual) { return 0; } 768 769 /* print and return true if just expected is NULL */ 770 if (expected == NULL) 771 { 772 UnityTestResultsFailBegin(lineNumber); 773 UnityPrint(UnityStrNullPointerForExpected); 774 UnityAddMsgIfSpecified(msg); 775 return 1; 776 } 777 778 /* print and return true if just actual is NULL */ 779 if (actual == NULL) 780 { 781 UnityTestResultsFailBegin(lineNumber); 782 UnityPrint(UnityStrNullPointerForActual); 783 UnityAddMsgIfSpecified(msg); 784 return 1; 785 } 786 787 return 0; /* return false if neither is NULL */ 788 } 789 790 /*----------------------------------------------- 791 * Assertion Functions 792 *-----------------------------------------------*/ 793 794 /*-----------------------------------------------*/ UnityAssertBits(const UNITY_INT mask,const UNITY_INT expected,const UNITY_INT actual,const char * msg,const UNITY_LINE_TYPE lineNumber)795 void UnityAssertBits(const UNITY_INT mask, 796 const UNITY_INT expected, 797 const UNITY_INT actual, 798 const char* msg, 799 const UNITY_LINE_TYPE lineNumber) 800 { 801 RETURN_IF_FAIL_OR_IGNORE; 802 803 if ((mask & expected) != (mask & actual)) 804 { 805 UnityTestResultsFailBegin(lineNumber); 806 UnityPrint(UnityStrExpected); 807 UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)expected); 808 UnityPrint(UnityStrWas); 809 UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)actual); 810 UnityAddMsgIfSpecified(msg); 811 UNITY_FAIL_AND_BAIL; 812 } 813 } 814 815 /*-----------------------------------------------*/ UnityAssertEqualNumber(const UNITY_INT expected,const UNITY_INT actual,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_DISPLAY_STYLE_T style)816 void UnityAssertEqualNumber(const UNITY_INT expected, 817 const UNITY_INT actual, 818 const char* msg, 819 const UNITY_LINE_TYPE lineNumber, 820 const UNITY_DISPLAY_STYLE_T style) 821 { 822 RETURN_IF_FAIL_OR_IGNORE; 823 824 if (expected != actual) 825 { 826 UnityTestResultsFailBegin(lineNumber); 827 UnityPrint(UnityStrExpected); 828 UnityPrintNumberByStyle(expected, style); 829 UnityPrint(UnityStrWas); 830 UnityPrintNumberByStyle(actual, style); 831 UnityAddMsgIfSpecified(msg); 832 UNITY_FAIL_AND_BAIL; 833 } 834 } 835 836 /*-----------------------------------------------*/ UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold,const UNITY_INT actual,const UNITY_COMPARISON_T compare,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_DISPLAY_STYLE_T style)837 void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold, 838 const UNITY_INT actual, 839 const UNITY_COMPARISON_T compare, 840 const char *msg, 841 const UNITY_LINE_TYPE lineNumber, 842 const UNITY_DISPLAY_STYLE_T style) 843 { 844 int failed = 0; 845 RETURN_IF_FAIL_OR_IGNORE; 846 847 if ((threshold == actual) && (compare & UNITY_EQUAL_TO)) { return; } 848 if ((threshold == actual)) { failed = 1; } 849 850 if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) 851 { 852 if ((actual > threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; } 853 if ((actual < threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; } 854 } 855 else /* UINT or HEX */ 856 { 857 if (((UNITY_UINT)actual > (UNITY_UINT)threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; } 858 if (((UNITY_UINT)actual < (UNITY_UINT)threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; } 859 } 860 861 if (failed) 862 { 863 UnityTestResultsFailBegin(lineNumber); 864 UnityPrint(UnityStrExpected); 865 UnityPrintNumberByStyle(actual, style); 866 if (compare & UNITY_GREATER_THAN) { UnityPrint(UnityStrGt); } 867 if (compare & UNITY_SMALLER_THAN) { UnityPrint(UnityStrLt); } 868 if (compare & UNITY_EQUAL_TO) { UnityPrint(UnityStrOrEqual); } 869 UnityPrintNumberByStyle(threshold, style); 870 UnityAddMsgIfSpecified(msg); 871 UNITY_FAIL_AND_BAIL; 872 } 873 } 874 875 #define UnityPrintPointlessAndBail() \ 876 { \ 877 UnityTestResultsFailBegin(lineNumber); \ 878 UnityPrint(UnityStrPointless); \ 879 UnityAddMsgIfSpecified(msg); \ 880 UNITY_FAIL_AND_BAIL; } 881 882 /*-----------------------------------------------*/ UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,UNITY_INTERNAL_PTR actual,const UNITY_UINT32 num_elements,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_DISPLAY_STYLE_T style,const UNITY_FLAGS_T flags)883 void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, 884 UNITY_INTERNAL_PTR actual, 885 const UNITY_UINT32 num_elements, 886 const char* msg, 887 const UNITY_LINE_TYPE lineNumber, 888 const UNITY_DISPLAY_STYLE_T style, 889 const UNITY_FLAGS_T flags) 890 { 891 UNITY_UINT32 elements = num_elements; 892 unsigned int length = style & 0xF; 893 unsigned int increment = 0; 894 895 RETURN_IF_FAIL_OR_IGNORE; 896 897 if (num_elements == 0) 898 { 899 UnityPrintPointlessAndBail(); 900 } 901 902 if (expected == actual) 903 { 904 return; /* Both are NULL or same pointer */ 905 } 906 907 if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) 908 { 909 UNITY_FAIL_AND_BAIL; 910 } 911 912 while ((elements > 0) && (elements--)) 913 { 914 UNITY_INT expect_val; 915 UNITY_INT actual_val; 916 917 switch (length) 918 { 919 case 1: 920 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected; 921 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual; 922 increment = sizeof(UNITY_INT8); 923 break; 924 925 case 2: 926 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected; 927 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual; 928 increment = sizeof(UNITY_INT16); 929 break; 930 931 #ifdef UNITY_SUPPORT_64 932 case 8: 933 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected; 934 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual; 935 increment = sizeof(UNITY_INT64); 936 break; 937 #endif 938 939 default: /* default is length 4 bytes */ 940 case 4: 941 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected; 942 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual; 943 increment = sizeof(UNITY_INT32); 944 length = 4; 945 break; 946 } 947 948 if (expect_val != actual_val) 949 { 950 if ((style & UNITY_DISPLAY_RANGE_UINT) && (length < (UNITY_INT_WIDTH / 8))) 951 { /* For UINT, remove sign extension (padding 1's) from signed type casts above */ 952 UNITY_INT mask = 1; 953 mask = (mask << 8 * length) - 1; 954 expect_val &= mask; 955 actual_val &= mask; 956 } 957 UnityTestResultsFailBegin(lineNumber); 958 UnityPrint(UnityStrElement); 959 UnityPrintNumberUnsigned(num_elements - elements - 1); 960 UnityPrint(UnityStrExpected); 961 UnityPrintNumberByStyle(expect_val, style); 962 UnityPrint(UnityStrWas); 963 UnityPrintNumberByStyle(actual_val, style); 964 UnityAddMsgIfSpecified(msg); 965 UNITY_FAIL_AND_BAIL; 966 } 967 /* Walk through array by incrementing the pointers */ 968 if (flags == UNITY_ARRAY_TO_ARRAY) 969 { 970 expected = (UNITY_INTERNAL_PTR)((const char*)expected + increment); 971 } 972 actual = (UNITY_INTERNAL_PTR)((const char*)actual + increment); 973 } 974 } 975 976 /*-----------------------------------------------*/ 977 #ifndef UNITY_EXCLUDE_FLOAT 978 /* Wrap this define in a function with variable types as float or double */ 979 #define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff) \ 980 if (isinf(expected) && isinf(actual) && (((expected) < 0) == ((actual) < 0))) return 1; \ 981 if (UNITY_NAN_CHECK) return 1; \ 982 (diff) = (actual) - (expected); \ 983 if ((diff) < 0) (diff) = -(diff); \ 984 if ((delta) < 0) (delta) = -(delta); \ 985 return !(isnan(diff) || isinf(diff) || ((diff) > (delta))) 986 /* This first part of this condition will catch any NaN or Infinite values */ 987 #ifndef UNITY_NAN_NOT_EQUAL_NAN 988 #define UNITY_NAN_CHECK isnan(expected) && isnan(actual) 989 #else 990 #define UNITY_NAN_CHECK 0 991 #endif 992 993 #ifndef UNITY_EXCLUDE_FLOAT_PRINT 994 #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \ 995 { \ 996 UnityPrint(UnityStrExpected); \ 997 UnityPrintFloat(expected); \ 998 UnityPrint(UnityStrWas); \ 999 UnityPrintFloat(actual); } 1000 #else 1001 #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \ 1002 UnityPrint(UnityStrDelta) 1003 #endif /* UNITY_EXCLUDE_FLOAT_PRINT */ 1004 1005 /*-----------------------------------------------*/ UnityFloatsWithin(UNITY_FLOAT delta,UNITY_FLOAT expected,UNITY_FLOAT actual)1006 static int UnityFloatsWithin(UNITY_FLOAT delta, UNITY_FLOAT expected, UNITY_FLOAT actual) 1007 { 1008 UNITY_FLOAT diff; 1009 UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); 1010 } 1011 1012 /*-----------------------------------------------*/ UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT * expected,UNITY_PTR_ATTRIBUTE const UNITY_FLOAT * actual,const UNITY_UINT32 num_elements,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLAGS_T flags)1013 void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected, 1014 UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual, 1015 const UNITY_UINT32 num_elements, 1016 const char* msg, 1017 const UNITY_LINE_TYPE lineNumber, 1018 const UNITY_FLAGS_T flags) 1019 { 1020 UNITY_UINT32 elements = num_elements; 1021 UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_expected = expected; 1022 UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_actual = actual; 1023 1024 RETURN_IF_FAIL_OR_IGNORE; 1025 1026 if (elements == 0) 1027 { 1028 UnityPrintPointlessAndBail(); 1029 } 1030 1031 if (expected == actual) 1032 { 1033 return; /* Both are NULL or same pointer */ 1034 } 1035 1036 if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) 1037 { 1038 UNITY_FAIL_AND_BAIL; 1039 } 1040 1041 while (elements--) 1042 { 1043 if (!UnityFloatsWithin(*ptr_expected * UNITY_FLOAT_PRECISION, *ptr_expected, *ptr_actual)) 1044 { 1045 UnityTestResultsFailBegin(lineNumber); 1046 UnityPrint(UnityStrElement); 1047 UnityPrintNumberUnsigned(num_elements - elements - 1); 1048 UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)*ptr_expected, (UNITY_DOUBLE)*ptr_actual); 1049 UnityAddMsgIfSpecified(msg); 1050 UNITY_FAIL_AND_BAIL; 1051 } 1052 if (flags == UNITY_ARRAY_TO_ARRAY) 1053 { 1054 ptr_expected++; 1055 } 1056 ptr_actual++; 1057 } 1058 } 1059 1060 /*-----------------------------------------------*/ UnityAssertFloatsWithin(const UNITY_FLOAT delta,const UNITY_FLOAT expected,const UNITY_FLOAT actual,const char * msg,const UNITY_LINE_TYPE lineNumber)1061 void UnityAssertFloatsWithin(const UNITY_FLOAT delta, 1062 const UNITY_FLOAT expected, 1063 const UNITY_FLOAT actual, 1064 const char* msg, 1065 const UNITY_LINE_TYPE lineNumber) 1066 { 1067 RETURN_IF_FAIL_OR_IGNORE; 1068 1069 1070 if (!UnityFloatsWithin(delta, expected, actual)) 1071 { 1072 UnityTestResultsFailBegin(lineNumber); 1073 UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual); 1074 UnityAddMsgIfSpecified(msg); 1075 UNITY_FAIL_AND_BAIL; 1076 } 1077 } 1078 1079 /*-----------------------------------------------*/ UnityAssertFloatSpecial(const UNITY_FLOAT actual,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLOAT_TRAIT_T style)1080 void UnityAssertFloatSpecial(const UNITY_FLOAT actual, 1081 const char* msg, 1082 const UNITY_LINE_TYPE lineNumber, 1083 const UNITY_FLOAT_TRAIT_T style) 1084 { 1085 const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet}; 1086 UNITY_INT should_be_trait = ((UNITY_INT)style & 1); 1087 UNITY_INT is_trait = !should_be_trait; 1088 UNITY_INT trait_index = (UNITY_INT)(style >> 1); 1089 1090 RETURN_IF_FAIL_OR_IGNORE; 1091 1092 switch (style) 1093 { 1094 case UNITY_FLOAT_IS_INF: 1095 case UNITY_FLOAT_IS_NOT_INF: 1096 is_trait = isinf(actual) && (actual > 0); 1097 break; 1098 case UNITY_FLOAT_IS_NEG_INF: 1099 case UNITY_FLOAT_IS_NOT_NEG_INF: 1100 is_trait = isinf(actual) && (actual < 0); 1101 break; 1102 1103 case UNITY_FLOAT_IS_NAN: 1104 case UNITY_FLOAT_IS_NOT_NAN: 1105 is_trait = isnan(actual) ? 1 : 0; 1106 break; 1107 1108 case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */ 1109 case UNITY_FLOAT_IS_NOT_DET: 1110 is_trait = !isinf(actual) && !isnan(actual); 1111 break; 1112 1113 default: 1114 trait_index = 0; 1115 trait_names[0] = UnityStrInvalidFloatTrait; 1116 break; 1117 } 1118 1119 if (is_trait != should_be_trait) 1120 { 1121 UnityTestResultsFailBegin(lineNumber); 1122 UnityPrint(UnityStrExpected); 1123 if (!should_be_trait) 1124 { 1125 UnityPrint(UnityStrNot); 1126 } 1127 UnityPrint(trait_names[trait_index]); 1128 UnityPrint(UnityStrWas); 1129 #ifndef UNITY_EXCLUDE_FLOAT_PRINT 1130 UnityPrintFloat((UNITY_DOUBLE)actual); 1131 #else 1132 if (should_be_trait) 1133 { 1134 UnityPrint(UnityStrNot); 1135 } 1136 UnityPrint(trait_names[trait_index]); 1137 #endif 1138 UnityAddMsgIfSpecified(msg); 1139 UNITY_FAIL_AND_BAIL; 1140 } 1141 } 1142 1143 #endif /* not UNITY_EXCLUDE_FLOAT */ 1144 1145 /*-----------------------------------------------*/ 1146 #ifndef UNITY_EXCLUDE_DOUBLE UnityDoublesWithin(UNITY_DOUBLE delta,UNITY_DOUBLE expected,UNITY_DOUBLE actual)1147 static int UnityDoublesWithin(UNITY_DOUBLE delta, UNITY_DOUBLE expected, UNITY_DOUBLE actual) 1148 { 1149 UNITY_DOUBLE diff; 1150 UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); 1151 } 1152 1153 /*-----------------------------------------------*/ UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE * expected,UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE * actual,const UNITY_UINT32 num_elements,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLAGS_T flags)1154 void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected, 1155 UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual, 1156 const UNITY_UINT32 num_elements, 1157 const char* msg, 1158 const UNITY_LINE_TYPE lineNumber, 1159 const UNITY_FLAGS_T flags) 1160 { 1161 UNITY_UINT32 elements = num_elements; 1162 UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_expected = expected; 1163 UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_actual = actual; 1164 1165 RETURN_IF_FAIL_OR_IGNORE; 1166 1167 if (elements == 0) 1168 { 1169 UnityPrintPointlessAndBail(); 1170 } 1171 1172 if (expected == actual) 1173 { 1174 return; /* Both are NULL or same pointer */ 1175 } 1176 1177 if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) 1178 { 1179 UNITY_FAIL_AND_BAIL; 1180 } 1181 1182 while (elements--) 1183 { 1184 if (!UnityDoublesWithin(*ptr_expected * UNITY_DOUBLE_PRECISION, *ptr_expected, *ptr_actual)) 1185 { 1186 UnityTestResultsFailBegin(lineNumber); 1187 UnityPrint(UnityStrElement); 1188 UnityPrintNumberUnsigned(num_elements - elements - 1); 1189 UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(*ptr_expected, *ptr_actual); 1190 UnityAddMsgIfSpecified(msg); 1191 UNITY_FAIL_AND_BAIL; 1192 } 1193 if (flags == UNITY_ARRAY_TO_ARRAY) 1194 { 1195 ptr_expected++; 1196 } 1197 ptr_actual++; 1198 } 1199 } 1200 1201 /*-----------------------------------------------*/ UnityAssertDoublesWithin(const UNITY_DOUBLE delta,const UNITY_DOUBLE expected,const UNITY_DOUBLE actual,const char * msg,const UNITY_LINE_TYPE lineNumber)1202 void UnityAssertDoublesWithin(const UNITY_DOUBLE delta, 1203 const UNITY_DOUBLE expected, 1204 const UNITY_DOUBLE actual, 1205 const char* msg, 1206 const UNITY_LINE_TYPE lineNumber) 1207 { 1208 RETURN_IF_FAIL_OR_IGNORE; 1209 1210 if (!UnityDoublesWithin(delta, expected, actual)) 1211 { 1212 UnityTestResultsFailBegin(lineNumber); 1213 UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual); 1214 UnityAddMsgIfSpecified(msg); 1215 UNITY_FAIL_AND_BAIL; 1216 } 1217 } 1218 1219 /*-----------------------------------------------*/ UnityAssertDoubleSpecial(const UNITY_DOUBLE actual,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLOAT_TRAIT_T style)1220 void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual, 1221 const char* msg, 1222 const UNITY_LINE_TYPE lineNumber, 1223 const UNITY_FLOAT_TRAIT_T style) 1224 { 1225 const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet}; 1226 UNITY_INT should_be_trait = ((UNITY_INT)style & 1); 1227 UNITY_INT is_trait = !should_be_trait; 1228 UNITY_INT trait_index = (UNITY_INT)(style >> 1); 1229 1230 RETURN_IF_FAIL_OR_IGNORE; 1231 1232 switch (style) 1233 { 1234 case UNITY_FLOAT_IS_INF: 1235 case UNITY_FLOAT_IS_NOT_INF: 1236 is_trait = isinf(actual) && (actual > 0); 1237 break; 1238 case UNITY_FLOAT_IS_NEG_INF: 1239 case UNITY_FLOAT_IS_NOT_NEG_INF: 1240 is_trait = isinf(actual) && (actual < 0); 1241 break; 1242 1243 case UNITY_FLOAT_IS_NAN: 1244 case UNITY_FLOAT_IS_NOT_NAN: 1245 is_trait = isnan(actual) ? 1 : 0; 1246 break; 1247 1248 case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */ 1249 case UNITY_FLOAT_IS_NOT_DET: 1250 is_trait = !isinf(actual) && !isnan(actual); 1251 break; 1252 1253 default: 1254 trait_index = 0; 1255 trait_names[0] = UnityStrInvalidFloatTrait; 1256 break; 1257 } 1258 1259 if (is_trait != should_be_trait) 1260 { 1261 UnityTestResultsFailBegin(lineNumber); 1262 UnityPrint(UnityStrExpected); 1263 if (!should_be_trait) 1264 { 1265 UnityPrint(UnityStrNot); 1266 } 1267 UnityPrint(trait_names[trait_index]); 1268 UnityPrint(UnityStrWas); 1269 #ifndef UNITY_EXCLUDE_FLOAT_PRINT 1270 UnityPrintFloat(actual); 1271 #else 1272 if (should_be_trait) 1273 { 1274 UnityPrint(UnityStrNot); 1275 } 1276 UnityPrint(trait_names[trait_index]); 1277 #endif 1278 UnityAddMsgIfSpecified(msg); 1279 UNITY_FAIL_AND_BAIL; 1280 } 1281 } 1282 1283 #endif /* not UNITY_EXCLUDE_DOUBLE */ 1284 1285 /*-----------------------------------------------*/ UnityAssertNumbersWithin(const UNITY_UINT delta,const UNITY_INT expected,const UNITY_INT actual,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_DISPLAY_STYLE_T style)1286 void UnityAssertNumbersWithin(const UNITY_UINT delta, 1287 const UNITY_INT expected, 1288 const UNITY_INT actual, 1289 const char* msg, 1290 const UNITY_LINE_TYPE lineNumber, 1291 const UNITY_DISPLAY_STYLE_T style) 1292 { 1293 RETURN_IF_FAIL_OR_IGNORE; 1294 1295 if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) 1296 { 1297 if (actual > expected) 1298 { 1299 Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta); 1300 } 1301 else 1302 { 1303 Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta); 1304 } 1305 } 1306 else 1307 { 1308 if ((UNITY_UINT)actual > (UNITY_UINT)expected) 1309 { 1310 Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta); 1311 } 1312 else 1313 { 1314 Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta); 1315 } 1316 } 1317 1318 if (Unity.CurrentTestFailed) 1319 { 1320 UnityTestResultsFailBegin(lineNumber); 1321 UnityPrint(UnityStrDelta); 1322 UnityPrintNumberByStyle((UNITY_INT)delta, style); 1323 UnityPrint(UnityStrExpected); 1324 UnityPrintNumberByStyle(expected, style); 1325 UnityPrint(UnityStrWas); 1326 UnityPrintNumberByStyle(actual, style); 1327 UnityAddMsgIfSpecified(msg); 1328 UNITY_FAIL_AND_BAIL; 1329 } 1330 } 1331 1332 /*-----------------------------------------------*/ UnityAssertNumbersArrayWithin(const UNITY_UINT delta,UNITY_INTERNAL_PTR expected,UNITY_INTERNAL_PTR actual,const UNITY_UINT32 num_elements,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_DISPLAY_STYLE_T style,const UNITY_FLAGS_T flags)1333 void UnityAssertNumbersArrayWithin(const UNITY_UINT delta, 1334 UNITY_INTERNAL_PTR expected, 1335 UNITY_INTERNAL_PTR actual, 1336 const UNITY_UINT32 num_elements, 1337 const char* msg, 1338 const UNITY_LINE_TYPE lineNumber, 1339 const UNITY_DISPLAY_STYLE_T style, 1340 const UNITY_FLAGS_T flags) 1341 { 1342 UNITY_UINT32 elements = num_elements; 1343 unsigned int length = style & 0xF; 1344 unsigned int increment = 0; 1345 1346 RETURN_IF_FAIL_OR_IGNORE; 1347 1348 if (num_elements == 0) 1349 { 1350 UnityPrintPointlessAndBail(); 1351 } 1352 1353 if (expected == actual) 1354 { 1355 return; /* Both are NULL or same pointer */ 1356 } 1357 1358 if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) 1359 { 1360 UNITY_FAIL_AND_BAIL; 1361 } 1362 1363 while ((elements > 0) && (elements--)) 1364 { 1365 UNITY_INT expect_val; 1366 UNITY_INT actual_val; 1367 1368 switch (length) 1369 { 1370 case 1: 1371 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected; 1372 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual; 1373 increment = sizeof(UNITY_INT8); 1374 break; 1375 1376 case 2: 1377 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected; 1378 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual; 1379 increment = sizeof(UNITY_INT16); 1380 break; 1381 1382 #ifdef UNITY_SUPPORT_64 1383 case 8: 1384 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected; 1385 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual; 1386 increment = sizeof(UNITY_INT64); 1387 break; 1388 #endif 1389 1390 default: /* default is length 4 bytes */ 1391 case 4: 1392 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected; 1393 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual; 1394 increment = sizeof(UNITY_INT32); 1395 length = 4; 1396 break; 1397 } 1398 1399 if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) 1400 { 1401 if (actual_val > expect_val) 1402 { 1403 Unity.CurrentTestFailed = (((UNITY_UINT)actual_val - (UNITY_UINT)expect_val) > delta); 1404 } 1405 else 1406 { 1407 Unity.CurrentTestFailed = (((UNITY_UINT)expect_val - (UNITY_UINT)actual_val) > delta); 1408 } 1409 } 1410 else 1411 { 1412 if ((UNITY_UINT)actual_val > (UNITY_UINT)expect_val) 1413 { 1414 Unity.CurrentTestFailed = (((UNITY_UINT)actual_val - (UNITY_UINT)expect_val) > delta); 1415 } 1416 else 1417 { 1418 Unity.CurrentTestFailed = (((UNITY_UINT)expect_val - (UNITY_UINT)actual_val) > delta); 1419 } 1420 } 1421 1422 if (Unity.CurrentTestFailed) 1423 { 1424 if ((style & UNITY_DISPLAY_RANGE_UINT) && (length < (UNITY_INT_WIDTH / 8))) 1425 { /* For UINT, remove sign extension (padding 1's) from signed type casts above */ 1426 UNITY_INT mask = 1; 1427 mask = (mask << 8 * length) - 1; 1428 expect_val &= mask; 1429 actual_val &= mask; 1430 } 1431 UnityTestResultsFailBegin(lineNumber); 1432 UnityPrint(UnityStrDelta); 1433 UnityPrintNumberByStyle((UNITY_INT)delta, style); 1434 UnityPrint(UnityStrElement); 1435 UnityPrintNumberUnsigned(num_elements - elements - 1); 1436 UnityPrint(UnityStrExpected); 1437 UnityPrintNumberByStyle(expect_val, style); 1438 UnityPrint(UnityStrWas); 1439 UnityPrintNumberByStyle(actual_val, style); 1440 UnityAddMsgIfSpecified(msg); 1441 UNITY_FAIL_AND_BAIL; 1442 } 1443 /* Walk through array by incrementing the pointers */ 1444 if (flags == UNITY_ARRAY_TO_ARRAY) 1445 { 1446 expected = (UNITY_INTERNAL_PTR)((const char*)expected + increment); 1447 } 1448 actual = (UNITY_INTERNAL_PTR)((const char*)actual + increment); 1449 } 1450 } 1451 1452 /*-----------------------------------------------*/ UnityAssertEqualString(const char * expected,const char * actual,const char * msg,const UNITY_LINE_TYPE lineNumber)1453 void UnityAssertEqualString(const char* expected, 1454 const char* actual, 1455 const char* msg, 1456 const UNITY_LINE_TYPE lineNumber) 1457 { 1458 UNITY_UINT32 i; 1459 1460 RETURN_IF_FAIL_OR_IGNORE; 1461 1462 /* if both pointers not null compare the strings */ 1463 if (expected && actual) 1464 { 1465 for (i = 0; expected[i] || actual[i]; i++) 1466 { 1467 if (expected[i] != actual[i]) 1468 { 1469 Unity.CurrentTestFailed = 1; 1470 break; 1471 } 1472 } 1473 } 1474 else 1475 { /* handle case of one pointers being null (if both null, test should pass) */ 1476 if (expected != actual) 1477 { 1478 Unity.CurrentTestFailed = 1; 1479 } 1480 } 1481 1482 if (Unity.CurrentTestFailed) 1483 { 1484 UnityTestResultsFailBegin(lineNumber); 1485 UnityPrintExpectedAndActualStrings(expected, actual); 1486 UnityAddMsgIfSpecified(msg); 1487 UNITY_FAIL_AND_BAIL; 1488 } 1489 } 1490 1491 /*-----------------------------------------------*/ UnityAssertEqualStringLen(const char * expected,const char * actual,const UNITY_UINT32 length,const char * msg,const UNITY_LINE_TYPE lineNumber)1492 void UnityAssertEqualStringLen(const char* expected, 1493 const char* actual, 1494 const UNITY_UINT32 length, 1495 const char* msg, 1496 const UNITY_LINE_TYPE lineNumber) 1497 { 1498 UNITY_UINT32 i; 1499 1500 RETURN_IF_FAIL_OR_IGNORE; 1501 1502 /* if both pointers not null compare the strings */ 1503 if (expected && actual) 1504 { 1505 for (i = 0; (i < length) && (expected[i] || actual[i]); i++) 1506 { 1507 if (expected[i] != actual[i]) 1508 { 1509 Unity.CurrentTestFailed = 1; 1510 break; 1511 } 1512 } 1513 } 1514 else 1515 { /* handle case of one pointers being null (if both null, test should pass) */ 1516 if (expected != actual) 1517 { 1518 Unity.CurrentTestFailed = 1; 1519 } 1520 } 1521 1522 if (Unity.CurrentTestFailed) 1523 { 1524 UnityTestResultsFailBegin(lineNumber); 1525 UnityPrintExpectedAndActualStringsLen(expected, actual, length); 1526 UnityAddMsgIfSpecified(msg); 1527 UNITY_FAIL_AND_BAIL; 1528 } 1529 } 1530 1531 /*-----------------------------------------------*/ UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,const char ** actual,const UNITY_UINT32 num_elements,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLAGS_T flags)1532 void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected, 1533 const char** actual, 1534 const UNITY_UINT32 num_elements, 1535 const char* msg, 1536 const UNITY_LINE_TYPE lineNumber, 1537 const UNITY_FLAGS_T flags) 1538 { 1539 UNITY_UINT32 i = 0; 1540 UNITY_UINT32 j = 0; 1541 const char* expd = NULL; 1542 const char* act = NULL; 1543 1544 RETURN_IF_FAIL_OR_IGNORE; 1545 1546 /* if no elements, it's an error */ 1547 if (num_elements == 0) 1548 { 1549 UnityPrintPointlessAndBail(); 1550 } 1551 1552 if ((const void*)expected == (const void*)actual) 1553 { 1554 return; /* Both are NULL or same pointer */ 1555 } 1556 1557 if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) 1558 { 1559 UNITY_FAIL_AND_BAIL; 1560 } 1561 1562 if (flags != UNITY_ARRAY_TO_ARRAY) 1563 { 1564 expd = (const char*)expected; 1565 } 1566 1567 do 1568 { 1569 act = actual[j]; 1570 if (flags == UNITY_ARRAY_TO_ARRAY) 1571 { 1572 expd = ((const char* const*)expected)[j]; 1573 } 1574 1575 /* if both pointers not null compare the strings */ 1576 if (expd && act) 1577 { 1578 for (i = 0; expd[i] || act[i]; i++) 1579 { 1580 if (expd[i] != act[i]) 1581 { 1582 Unity.CurrentTestFailed = 1; 1583 break; 1584 } 1585 } 1586 } 1587 else 1588 { /* handle case of one pointers being null (if both null, test should pass) */ 1589 if (expd != act) 1590 { 1591 Unity.CurrentTestFailed = 1; 1592 } 1593 } 1594 1595 if (Unity.CurrentTestFailed) 1596 { 1597 UnityTestResultsFailBegin(lineNumber); 1598 if (num_elements > 1) 1599 { 1600 UnityPrint(UnityStrElement); 1601 UnityPrintNumberUnsigned(j); 1602 } 1603 UnityPrintExpectedAndActualStrings(expd, act); 1604 UnityAddMsgIfSpecified(msg); 1605 UNITY_FAIL_AND_BAIL; 1606 } 1607 } while (++j < num_elements); 1608 } 1609 1610 /*-----------------------------------------------*/ UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected,UNITY_INTERNAL_PTR actual,const UNITY_UINT32 length,const UNITY_UINT32 num_elements,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLAGS_T flags)1611 void UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected, 1612 UNITY_INTERNAL_PTR actual, 1613 const UNITY_UINT32 length, 1614 const UNITY_UINT32 num_elements, 1615 const char* msg, 1616 const UNITY_LINE_TYPE lineNumber, 1617 const UNITY_FLAGS_T flags) 1618 { 1619 UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; 1620 UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual; 1621 UNITY_UINT32 elements = num_elements; 1622 UNITY_UINT32 bytes; 1623 1624 RETURN_IF_FAIL_OR_IGNORE; 1625 1626 if ((elements == 0) || (length == 0)) 1627 { 1628 UnityPrintPointlessAndBail(); 1629 } 1630 1631 if (expected == actual) 1632 { 1633 return; /* Both are NULL or same pointer */ 1634 } 1635 1636 if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) 1637 { 1638 UNITY_FAIL_AND_BAIL; 1639 } 1640 1641 while (elements--) 1642 { 1643 bytes = length; 1644 while (bytes--) 1645 { 1646 if (*ptr_exp != *ptr_act) 1647 { 1648 UnityTestResultsFailBegin(lineNumber); 1649 UnityPrint(UnityStrMemory); 1650 if (num_elements > 1) 1651 { 1652 UnityPrint(UnityStrElement); 1653 UnityPrintNumberUnsigned(num_elements - elements - 1); 1654 } 1655 UnityPrint(UnityStrByte); 1656 UnityPrintNumberUnsigned(length - bytes - 1); 1657 UnityPrint(UnityStrExpected); 1658 UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8); 1659 UnityPrint(UnityStrWas); 1660 UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8); 1661 UnityAddMsgIfSpecified(msg); 1662 UNITY_FAIL_AND_BAIL; 1663 } 1664 ptr_exp++; 1665 ptr_act++; 1666 } 1667 if (flags == UNITY_ARRAY_TO_VAL) 1668 { 1669 ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; 1670 } 1671 } 1672 } 1673 1674 /*-----------------------------------------------*/ 1675 1676 static union 1677 { 1678 UNITY_INT8 i8; 1679 UNITY_INT16 i16; 1680 UNITY_INT32 i32; 1681 #ifdef UNITY_SUPPORT_64 1682 UNITY_INT64 i64; 1683 #endif 1684 #ifndef UNITY_EXCLUDE_FLOAT 1685 float f; 1686 #endif 1687 #ifndef UNITY_EXCLUDE_DOUBLE 1688 double d; 1689 #endif 1690 } UnityQuickCompare; 1691 UnityNumToPtr(const UNITY_INT num,const UNITY_UINT8 size)1692 UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size) 1693 { 1694 switch(size) 1695 { 1696 case 1: 1697 UnityQuickCompare.i8 = (UNITY_INT8)num; 1698 return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i8); 1699 1700 case 2: 1701 UnityQuickCompare.i16 = (UNITY_INT16)num; 1702 return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i16); 1703 1704 #ifdef UNITY_SUPPORT_64 1705 case 8: 1706 UnityQuickCompare.i64 = (UNITY_INT64)num; 1707 return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i64); 1708 #endif 1709 1710 default: /* 4 bytes */ 1711 UnityQuickCompare.i32 = (UNITY_INT32)num; 1712 return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i32); 1713 } 1714 } 1715 1716 #ifndef UNITY_EXCLUDE_FLOAT 1717 /*-----------------------------------------------*/ UnityFloatToPtr(const float num)1718 UNITY_INTERNAL_PTR UnityFloatToPtr(const float num) 1719 { 1720 UnityQuickCompare.f = num; 1721 return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.f); 1722 } 1723 #endif 1724 1725 #ifndef UNITY_EXCLUDE_DOUBLE 1726 /*-----------------------------------------------*/ UnityDoubleToPtr(const double num)1727 UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num) 1728 { 1729 UnityQuickCompare.d = num; 1730 return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.d); 1731 } 1732 #endif 1733 1734 /*----------------------------------------------- 1735 * Control Functions 1736 *-----------------------------------------------*/ 1737 1738 /*-----------------------------------------------*/ UnityFail(const char * msg,const UNITY_LINE_TYPE line)1739 void UnityFail(const char* msg, const UNITY_LINE_TYPE line) 1740 { 1741 RETURN_IF_FAIL_OR_IGNORE; 1742 1743 UnityTestResultsBegin(Unity.TestFile, line); 1744 UnityPrint(UnityStrFail); 1745 if (msg != NULL) 1746 { 1747 UNITY_OUTPUT_CHAR(':'); 1748 1749 #ifndef UNITY_EXCLUDE_DETAILS 1750 if (Unity.CurrentDetail1) 1751 { 1752 UnityPrint(UnityStrDetail1Name); 1753 UnityPrint(Unity.CurrentDetail1); 1754 if (Unity.CurrentDetail2) 1755 { 1756 UnityPrint(UnityStrDetail2Name); 1757 UnityPrint(Unity.CurrentDetail2); 1758 } 1759 UnityPrint(UnityStrSpacer); 1760 } 1761 #endif 1762 if (msg[0] != ' ') 1763 { 1764 UNITY_OUTPUT_CHAR(' '); 1765 } 1766 UnityPrint(msg); 1767 } 1768 1769 UNITY_FAIL_AND_BAIL; 1770 } 1771 1772 /*-----------------------------------------------*/ UnityIgnore(const char * msg,const UNITY_LINE_TYPE line)1773 void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) 1774 { 1775 RETURN_IF_FAIL_OR_IGNORE; 1776 1777 UnityTestResultsBegin(Unity.TestFile, line); 1778 UnityPrint(UnityStrIgnore); 1779 if (msg != NULL) 1780 { 1781 UNITY_OUTPUT_CHAR(':'); 1782 UNITY_OUTPUT_CHAR(' '); 1783 UnityPrint(msg); 1784 } 1785 UNITY_IGNORE_AND_BAIL; 1786 } 1787 1788 /*-----------------------------------------------*/ UnityMessage(const char * msg,const UNITY_LINE_TYPE line)1789 void UnityMessage(const char* msg, const UNITY_LINE_TYPE line) 1790 { 1791 UnityTestResultsBegin(Unity.TestFile, line); 1792 UnityPrint("INFO"); 1793 if (msg != NULL) 1794 { 1795 UNITY_OUTPUT_CHAR(':'); 1796 UNITY_OUTPUT_CHAR(' '); 1797 UnityPrint(msg); 1798 } 1799 UNITY_PRINT_EOL(); 1800 } 1801 1802 /*-----------------------------------------------*/ UnityDefaultTestRun(UnityTestFunction Func,const char * FuncName,const int FuncLineNum)1803 void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) 1804 { 1805 Unity.CurrentTestName = FuncName; 1806 Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; 1807 Unity.NumberOfTests++; 1808 UNITY_CLR_DETAILS(); 1809 UNITY_EXEC_TIME_START(); 1810 if (TEST_PROTECT()) 1811 { 1812 setUp(); 1813 Func(); 1814 } 1815 if (TEST_PROTECT()) 1816 { 1817 tearDown(); 1818 } 1819 UNITY_EXEC_TIME_STOP(); 1820 UnityConcludeTest(); 1821 } 1822 1823 /*-----------------------------------------------*/ UnitySetTestFile(const char * filename)1824 void UnitySetTestFile(const char* filename) 1825 { 1826 Unity.TestFile = filename; 1827 } 1828 1829 /*-----------------------------------------------*/ UnityBegin(const char * filename)1830 void UnityBegin(const char* filename) 1831 { 1832 Unity.TestFile = filename; 1833 Unity.CurrentTestName = NULL; 1834 Unity.CurrentTestLineNumber = 0; 1835 Unity.NumberOfTests = 0; 1836 Unity.TestFailures = 0; 1837 Unity.TestIgnores = 0; 1838 Unity.CurrentTestFailed = 0; 1839 Unity.CurrentTestIgnored = 0; 1840 1841 UNITY_CLR_DETAILS(); 1842 UNITY_OUTPUT_START(); 1843 } 1844 1845 /*-----------------------------------------------*/ UnityEnd(void)1846 int UnityEnd(void) 1847 { 1848 UNITY_PRINT_EOL(); 1849 UnityPrint(UnityStrBreaker); 1850 UNITY_PRINT_EOL(); 1851 UnityPrintNumber((UNITY_INT)(Unity.NumberOfTests)); 1852 UnityPrint(UnityStrResultsTests); 1853 UnityPrintNumber((UNITY_INT)(Unity.TestFailures)); 1854 UnityPrint(UnityStrResultsFailures); 1855 UnityPrintNumber((UNITY_INT)(Unity.TestIgnores)); 1856 UnityPrint(UnityStrResultsIgnored); 1857 UNITY_PRINT_EOL(); 1858 if (Unity.TestFailures == 0U) 1859 { 1860 UnityPrint(UnityStrOk); 1861 } 1862 else 1863 { 1864 UnityPrint(UnityStrFail); 1865 #ifdef UNITY_DIFFERENTIATE_FINAL_FAIL 1866 UNITY_OUTPUT_CHAR('E'); UNITY_OUTPUT_CHAR('D'); 1867 #endif 1868 } 1869 UNITY_PRINT_EOL(); 1870 UNITY_FLUSH_CALL(); 1871 UNITY_OUTPUT_COMPLETE(); 1872 return (int)(Unity.TestFailures); 1873 } 1874 1875 /*----------------------------------------------- 1876 * Command Line Argument Support 1877 *-----------------------------------------------*/ 1878 #ifdef UNITY_USE_COMMAND_LINE_ARGS 1879 1880 char* UnityOptionIncludeNamed = NULL; 1881 char* UnityOptionExcludeNamed = NULL; 1882 int UnityVerbosity = 1; 1883 1884 /*-----------------------------------------------*/ UnityParseOptions(int argc,char ** argv)1885 int UnityParseOptions(int argc, char** argv) 1886 { 1887 int i; 1888 UnityOptionIncludeNamed = NULL; 1889 UnityOptionExcludeNamed = NULL; 1890 1891 for (i = 1; i < argc; i++) 1892 { 1893 if (argv[i][0] == '-') 1894 { 1895 switch (argv[i][1]) 1896 { 1897 case 'l': /* list tests */ 1898 return -1; 1899 case 'n': /* include tests with name including this string */ 1900 case 'f': /* an alias for -n */ 1901 if (argv[i][2] == '=') 1902 { 1903 UnityOptionIncludeNamed = &argv[i][3]; 1904 } 1905 else if (++i < argc) 1906 { 1907 UnityOptionIncludeNamed = argv[i]; 1908 } 1909 else 1910 { 1911 UnityPrint("ERROR: No Test String to Include Matches For"); 1912 UNITY_PRINT_EOL(); 1913 return 1; 1914 } 1915 break; 1916 case 'q': /* quiet */ 1917 UnityVerbosity = 0; 1918 break; 1919 case 'v': /* verbose */ 1920 UnityVerbosity = 2; 1921 break; 1922 case 'x': /* exclude tests with name including this string */ 1923 if (argv[i][2] == '=') 1924 { 1925 UnityOptionExcludeNamed = &argv[i][3]; 1926 } 1927 else if (++i < argc) 1928 { 1929 UnityOptionExcludeNamed = argv[i]; 1930 } 1931 else 1932 { 1933 UnityPrint("ERROR: No Test String to Exclude Matches For"); 1934 UNITY_PRINT_EOL(); 1935 return 1; 1936 } 1937 break; 1938 default: 1939 UnityPrint("ERROR: Unknown Option "); 1940 UNITY_OUTPUT_CHAR(argv[i][1]); 1941 UNITY_PRINT_EOL(); 1942 return 1; 1943 } 1944 } 1945 } 1946 1947 return 0; 1948 } 1949 1950 /*-----------------------------------------------*/ IsStringInBiggerString(const char * longstring,const char * shortstring)1951 int IsStringInBiggerString(const char* longstring, const char* shortstring) 1952 { 1953 const char* lptr = longstring; 1954 const char* sptr = shortstring; 1955 const char* lnext = lptr; 1956 1957 if (*sptr == '*') 1958 { 1959 return 1; 1960 } 1961 1962 while (*lptr) 1963 { 1964 lnext = lptr + 1; 1965 1966 /* If they current bytes match, go on to the next bytes */ 1967 while (*lptr && *sptr && (*lptr == *sptr)) 1968 { 1969 lptr++; 1970 sptr++; 1971 1972 /* We're done if we match the entire string or up to a wildcard */ 1973 if (*sptr == '*') 1974 return 1; 1975 if (*sptr == ',') 1976 return 1; 1977 if (*sptr == '"') 1978 return 1; 1979 if (*sptr == '\'') 1980 return 1; 1981 if (*sptr == ':') 1982 return 2; 1983 if (*sptr == 0) 1984 return 1; 1985 } 1986 1987 /* Otherwise we start in the long pointer 1 character further and try again */ 1988 lptr = lnext; 1989 sptr = shortstring; 1990 } 1991 1992 return 0; 1993 } 1994 1995 /*-----------------------------------------------*/ UnityStringArgumentMatches(const char * str)1996 int UnityStringArgumentMatches(const char* str) 1997 { 1998 int retval; 1999 const char* ptr1; 2000 const char* ptr2; 2001 const char* ptrf; 2002 2003 /* Go through the options and get the substrings for matching one at a time */ 2004 ptr1 = str; 2005 while (ptr1[0] != 0) 2006 { 2007 if ((ptr1[0] == '"') || (ptr1[0] == '\'')) 2008 { 2009 ptr1++; 2010 } 2011 2012 /* look for the start of the next partial */ 2013 ptr2 = ptr1; 2014 ptrf = 0; 2015 do 2016 { 2017 ptr2++; 2018 if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')) 2019 { 2020 ptrf = &ptr2[1]; 2021 } 2022 } while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')); 2023 2024 while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ','))) 2025 { 2026 ptr2++; 2027 } 2028 2029 /* done if complete filename match */ 2030 retval = IsStringInBiggerString(Unity.TestFile, ptr1); 2031 if (retval == 1) 2032 { 2033 return retval; 2034 } 2035 2036 /* done if testname match after filename partial match */ 2037 if ((retval == 2) && (ptrf != 0)) 2038 { 2039 if (IsStringInBiggerString(Unity.CurrentTestName, ptrf)) 2040 { 2041 return 1; 2042 } 2043 } 2044 2045 /* done if complete testname match */ 2046 if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1) 2047 { 2048 return 1; 2049 } 2050 2051 ptr1 = ptr2; 2052 } 2053 2054 /* we couldn't find a match for any substrings */ 2055 return 0; 2056 } 2057 2058 /*-----------------------------------------------*/ UnityTestMatches(void)2059 int UnityTestMatches(void) 2060 { 2061 /* Check if this test name matches the included test pattern */ 2062 int retval; 2063 if (UnityOptionIncludeNamed) 2064 { 2065 retval = UnityStringArgumentMatches(UnityOptionIncludeNamed); 2066 } 2067 else 2068 { 2069 retval = 1; 2070 } 2071 2072 /* Check if this test name matches the excluded test pattern */ 2073 if (UnityOptionExcludeNamed) 2074 { 2075 if (UnityStringArgumentMatches(UnityOptionExcludeNamed)) 2076 { 2077 retval = 0; 2078 } 2079 } 2080 2081 return retval; 2082 } 2083 2084 #endif /* UNITY_USE_COMMAND_LINE_ARGS */ 2085 /*-----------------------------------------------*/ 2086