exercism

Exercism solutions.
git clone git://code.dwrz.net/exercism
Log | Files | Refs

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 /*-----------------------------------------------*/