unity.c 55.6 KB
Newer Older
M
Mark VanderVoord 已提交
1 2 3 4 5 6
/* =========================================================================
    Unity Project - A Test Framework for C
    Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams
    [Released under MIT License. Please refer to license.txt for details]
============================================================================ */

J
John Lindgren 已提交
7
#define UNITY_INCLUDE_SETUP_STUBS
M
Mark VanderVoord 已提交
8 9 10
#include "unity.h"
#include <stddef.h>

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 15
#endif

16
/* Helpful macros for us to use here in Assert functions */
17 18
#define UNITY_FAIL_AND_BAIL   { Unity.CurrentTestFailed  = 1; UNITY_OUTPUT_FLUSH(); TEST_ABORT(); }
#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; UNITY_OUTPUT_FLUSH(); TEST_ABORT(); }
19
#define RETURN_IF_FAIL_OR_IGNORE if (Unity.CurrentTestFailed || Unity.CurrentTestIgnored) return
M
Mark VanderVoord 已提交
20

21
struct UNITY_STORAGE_T Unity;
M
Mark VanderVoord 已提交
22

23 24 25 26 27 28
#ifdef UNITY_OUTPUT_COLOR
static const char UnityStrOk[]                     = "\033[42mOK\033[00m";
static const char UnityStrPass[]                   = "\033[42mPASS\033[00m";
static const char UnityStrFail[]                   = "\033[41mFAIL\033[00m";
static const char UnityStrIgnore[]                 = "\033[43mIGNORE\033[00m";
#else
29 30 31 32
static const char UnityStrOk[]                     = "OK";
static const char UnityStrPass[]                   = "PASS";
static const char UnityStrFail[]                   = "FAIL";
static const char UnityStrIgnore[]                 = "IGNORE";
33
#endif
34 35 36 37
static const char UnityStrNull[]                   = "NULL";
static const char UnityStrSpacer[]                 = ". ";
static const char UnityStrExpected[]               = " Expected ";
static const char UnityStrWas[]                    = " Was ";
38 39
static const char UnityStrGt[]                     = " to be greater than ";
static const char UnityStrLt[]                     = " to be less than ";
40
static const char UnityStrOrEqual[]                = "or equal to ";
41 42 43 44 45 46 47
static const char UnityStrElement[]                = " Element ";
static const char UnityStrByte[]                   = " Byte ";
static const char UnityStrMemory[]                 = " Memory Mismatch.";
static const char UnityStrDelta[]                  = " Values Not Within Delta ";
static const char UnityStrPointless[]              = " You Asked Me To Compare Nothing, Which Was Pointless.";
static const char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL";
static const char UnityStrNullPointerForActual[]   = " Actual pointer was NULL";
48
#ifndef UNITY_EXCLUDE_FLOAT
49 50 51 52 53 54
static const char UnityStrNot[]                    = "Not ";
static const char UnityStrInf[]                    = "Infinity";
static const char UnityStrNegInf[]                 = "Negative Infinity";
static const char UnityStrNaN[]                    = "NaN";
static const char UnityStrDet[]                    = "Determinate";
static const char UnityStrInvalidFloatTrait[]      = "Invalid Float Trait";
55
#endif
56 57 58 59 60 61 62 63 64
const char UnityStrErrFloat[]                      = "Unity Floating Point Disabled";
const char UnityStrErrDouble[]                     = "Unity Double Precision Disabled";
const char UnityStrErr64[]                         = "Unity 64-bit Support Disabled";
static const char UnityStrBreaker[]                = "-----------------------";
static const char UnityStrResultsTests[]           = " Tests ";
static const char UnityStrResultsFailures[]        = " Failures ";
static const char UnityStrResultsIgnored[]         = " Ignored ";
static const char UnityStrDetail1Name[]            = UNITY_DETAIL1_NAME " ";
static const char UnityStrDetail2Name[]            = " " UNITY_DETAIL2_NAME " ";
M
Mark VanderVoord 已提交
65

66 67 68
/*-----------------------------------------------
 * Pretty Printers & Test Result Output Handlers
 *-----------------------------------------------*/
M
Mark VanderVoord 已提交
69

F
Fabian Zahn 已提交
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
/*-----------------------------------------------*/
/* Local helper function to print characters. */
static void UnityPrintChar(const char* pch)
{
    /* printable characters plus CR & LF are printed */
    if ((*pch <= 126) && (*pch >= 32))
    {
        UNITY_OUTPUT_CHAR(*pch);
    }
    /* write escaped carriage returns */
    else if (*pch == 13)
    {
        UNITY_OUTPUT_CHAR('\\');
        UNITY_OUTPUT_CHAR('r');
    }
    /* write escaped line feeds */
    else if (*pch == 10)
    {
        UNITY_OUTPUT_CHAR('\\');
        UNITY_OUTPUT_CHAR('n');
    }
    /* unprintable characters are shown as codes */
    else
    {
        UNITY_OUTPUT_CHAR('\\');
        UNITY_OUTPUT_CHAR('x');
        UnityPrintNumberHex((UNITY_UINT)*pch, 2);
    }
}

/*-----------------------------------------------*/
#ifdef UNITY_OUTPUT_COLOR
static UNITY_UINT UnityPrintAnsiEscapeString(const char* string)
{
    const char* pch = string;
    UNITY_UINT count = 0;

    while (*pch && *pch != 'm')
    {
        UNITY_OUTPUT_CHAR(*pch);
        pch++;
        count++;
    }
    UNITY_OUTPUT_CHAR('m');
    count++;

    return count;
}
#endif

/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
121 122 123 124 125 126 127 128
void UnityPrint(const char* string)
{
    const char* pch = string;

    if (pch != NULL)
    {
        while (*pch)
        {
F
Fabian Zahn 已提交
129 130 131
#ifdef UNITY_OUTPUT_COLOR
            /* print ANSI escape code */
            if (*pch == 27 && *(pch + 1) == '[')
M
Mark VanderVoord 已提交
132
            {
F
Fabian Zahn 已提交
133 134
                pch += UnityPrintAnsiEscapeString(pch);
                continue;
M
Mark VanderVoord 已提交
135
            }
F
Fabian Zahn 已提交
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
#endif
            UnityPrintChar(pch);
            pch++;
        }
    }
}

/*-----------------------------------------------*/
#ifndef UNITY_EXCLUDE_PRINT_FORMATTED
void UnityPrintFormatted(const char* format, ... )
{
    const char* pch = format;
    va_list va;
    va_start(va, format);

    if (pch != NULL)
    {
        while (*pch)
        {
            /* format identification character */
            if (*pch == '%')
M
Mark VanderVoord 已提交
157
            {
F
Fabian Zahn 已提交
158 159 160 161 162 163 164 165 166
                pch++;

                if (pch != NULL)
                {
                    switch (*pch)
                    {
                        case 'd':
                        case 'i':
                            {
167 168
                                const int number = va_arg(va, int);
                                UnityPrintNumber((UNITY_INT)number);
F
Fabian Zahn 已提交
169 170
                                break;
                            }
171 172 173 174 175 176 177 178 179
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
                        case 'f':
                        case 'g':
                            {
                                const double number = va_arg(va, double);
                                UnityPrintFloat((UNITY_DOUBLE)number);
                                break;
                            }
#endif
F
Fabian Zahn 已提交
180 181
                        case 'u':
                            {
182 183 184 185 186 187 188 189 190 191 192
                                const unsigned int number = va_arg(va, unsigned int);
                                UnityPrintNumberUnsigned((UNITY_UINT)number);
                                break;
                            }
                        case 'b':
                            {
                                const unsigned int number = va_arg(va, unsigned int);
                                const UNITY_UINT mask = (UNITY_UINT)0 - (UNITY_UINT)1;
                                UNITY_OUTPUT_CHAR('0');
                                UNITY_OUTPUT_CHAR('b');
                                UnityPrintMask(mask, (UNITY_UINT)number);
F
Fabian Zahn 已提交
193 194 195 196 197 198
                                break;
                            }
                        case 'x':
                        case 'X':
                        case 'p':
                            {
199
                                const unsigned int number = va_arg(va, unsigned int);
F
Fabian Zahn 已提交
200 201
                                UNITY_OUTPUT_CHAR('0');
                                UNITY_OUTPUT_CHAR('x');
202
                                UnityPrintNumberHex((UNITY_UINT)number, 8);
F
Fabian Zahn 已提交
203 204 205 206
                                break;
                            }
                        case 'c':
                            {
207
                                const int ch = va_arg(va, int);
F
Fabian Zahn 已提交
208 209 210 211 212 213 214 215 216
                                UnityPrintChar((const char *)&ch);
                                break;
                            }
                        case 's':
                            {   const char * string = va_arg(va, const char *);
                                UnityPrint(string);
                                break;
                            }
                        case '%':
217 218 219 220
                            {
                                UnityPrintChar(pch);
                                break;
                            }
F
Fabian Zahn 已提交
221
                        default:
222 223 224 225 226 227
                            {
                                /* print the unknown character */
                                UNITY_OUTPUT_CHAR('%');
                                UnityPrintChar(pch);
                                break;
                            }
F
Fabian Zahn 已提交
228 229
                    }
                }
M
Mark VanderVoord 已提交
230
            }
231 232 233 234
#ifdef UNITY_OUTPUT_COLOR
            /* print ANSI escape code */
            else if (*pch == 27 && *(pch + 1) == '[')
            {
F
Fabian Zahn 已提交
235 236
                pch += UnityPrintAnsiEscapeString(pch);
                continue;
237 238
            }
#endif
F
Fabian Zahn 已提交
239 240 241 242
            else if (*pch == '\n')
            {
                UNITY_PRINT_EOL();
            }
M
Mark VanderVoord 已提交
243 244
            else
            {
F
Fabian Zahn 已提交
245
                UnityPrintChar(pch);
M
Mark VanderVoord 已提交
246
            }
F
Fabian Zahn 已提交
247

M
Mark VanderVoord 已提交
248 249 250
            pch++;
        }
    }
F
Fabian Zahn 已提交
251 252

    va_end(va);
M
Mark VanderVoord 已提交
253
}
F
Fabian Zahn 已提交
254
#endif /* ! UNITY_EXCLUDE_PRINT_FORMATTED */
M
Mark VanderVoord 已提交
255

F
Fabian Zahn 已提交
256
/*-----------------------------------------------*/
257
void UnityPrintLen(const char* string, const UNITY_UINT32 length)
M
Mark VanderVoord 已提交
258 259 260 261 262
{
    const char* pch = string;

    if (pch != NULL)
    {
263
        while (*pch && (UNITY_UINT32)(pch - string) < length)
M
Mark VanderVoord 已提交
264
        {
265
            /* printable characters plus CR & LF are printed */
M
Mark VanderVoord 已提交
266 267 268 269
            if ((*pch <= 126) && (*pch >= 32))
            {
                UNITY_OUTPUT_CHAR(*pch);
            }
270
            /* write escaped carriage returns */
M
Mark VanderVoord 已提交
271 272 273 274 275
            else if (*pch == 13)
            {
                UNITY_OUTPUT_CHAR('\\');
                UNITY_OUTPUT_CHAR('r');
            }
276
            /* write escaped line feeds */
M
Mark VanderVoord 已提交
277 278 279 280 281
            else if (*pch == 10)
            {
                UNITY_OUTPUT_CHAR('\\');
                UNITY_OUTPUT_CHAR('n');
            }
282
            /* unprintable characters are shown as codes */
M
Mark VanderVoord 已提交
283 284 285
            else
            {
                UNITY_OUTPUT_CHAR('\\');
286
                UNITY_OUTPUT_CHAR('x');
287
                UnityPrintNumberHex((UNITY_UINT)*pch, 2);
M
Mark VanderVoord 已提交
288 289 290 291 292 293
            }
            pch++;
        }
    }
}

294
/*-----------------------------------------------*/
295
void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style)
M
Mark VanderVoord 已提交
296 297 298 299 300 301 302
{
    if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
    {
        UnityPrintNumber(number);
    }
    else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT)
    {
303
        UnityPrintNumberUnsigned((UNITY_UINT)number);
M
Mark VanderVoord 已提交
304 305 306
    }
    else
    {
307 308
        UNITY_OUTPUT_CHAR('0');
        UNITY_OUTPUT_CHAR('x');
309
        UnityPrintNumberHex((UNITY_UINT)number, (char)((style & 0xF) * 2));
M
Mark VanderVoord 已提交
310 311 312
    }
}

313
/*-----------------------------------------------*/
314
void UnityPrintNumber(const UNITY_INT number_to_print)
M
Mark VanderVoord 已提交
315
{
316
    UNITY_UINT number = (UNITY_UINT)number_to_print;
M
Mark VanderVoord 已提交
317 318 319

    if (number_to_print < 0)
    {
320
        /* A negative number, including MIN negative */
M
Mark VanderVoord 已提交
321
        UNITY_OUTPUT_CHAR('-');
322
        number = -number;
M
Mark VanderVoord 已提交
323
    }
324
    UnityPrintNumberUnsigned(number);
M
Mark VanderVoord 已提交
325 326
}

327 328
/*-----------------------------------------------
 * basically do an itoa using as little ram as possible */
329
void UnityPrintNumberUnsigned(const UNITY_UINT number)
M
Mark VanderVoord 已提交
330
{
331
    UNITY_UINT divisor = 1;
M
Mark VanderVoord 已提交
332

333
    /* figure out initial divisor */
M
Mark VanderVoord 已提交
334 335
    while (number / divisor > 9)
    {
336
        divisor *= 10;
M
Mark VanderVoord 已提交
337 338
    }

339
    /* now mod and print, then divide divisor */
M
Mark VanderVoord 已提交
340 341 342 343
    do
    {
        UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
        divisor /= 10;
344
    } while (divisor > 0);
M
Mark VanderVoord 已提交
345 346
}

347
/*-----------------------------------------------*/
348
void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print)
M
Mark VanderVoord 已提交
349
{
350
    int nibble;
M
Mark VanderVoord 已提交
351
    char nibbles = nibbles_to_print;
352
    if ((unsigned)nibbles > (2 * sizeof(number)))
K
Kochise 已提交
353
    {
354
        nibbles = 2 * sizeof(number);
K
Kochise 已提交
355
    }
M
Mark VanderVoord 已提交
356 357 358

    while (nibbles > 0)
    {
359
        nibbles--;
360
        nibble = (int)(number >> (nibbles * 4)) & 0x0F;
M
Mark VanderVoord 已提交
361 362 363 364 365 366 367 368 369 370 371
        if (nibble <= 9)
        {
            UNITY_OUTPUT_CHAR((char)('0' + nibble));
        }
        else
        {
            UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble));
        }
    }
}

372
/*-----------------------------------------------*/
373
void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number)
M
Mark VanderVoord 已提交
374
{
375 376
    UNITY_UINT current_bit = (UNITY_UINT)1 << (UNITY_INT_WIDTH - 1);
    UNITY_INT32 i;
M
Mark VanderVoord 已提交
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398

    for (i = 0; i < UNITY_INT_WIDTH; i++)
    {
        if (current_bit & mask)
        {
            if (current_bit & number)
            {
                UNITY_OUTPUT_CHAR('1');
            }
            else
            {
                UNITY_OUTPUT_CHAR('0');
            }
        }
        else
        {
            UNITY_OUTPUT_CHAR('X');
        }
        current_bit = current_bit >> 1;
    }
}

399
/*-----------------------------------------------*/
J
jsalling 已提交
400
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
401 402
/*
 * This function prints a floating-point value in a format similar to
403 404 405 406
 * printf("%.7g") on a single-precision machine or printf("%.9g") on a
 * double-precision machine.  The 7th digit won't always be totally correct
 * in single-precision operation (for that level of accuracy, a more
 * complicated algorithm would be needed).
407
 */
408
void UnityPrintFloat(const UNITY_DOUBLE input_number)
M
Mark VanderVoord 已提交
409
{
410 411 412 413 414 415 416 417 418 419
#ifdef UNITY_INCLUDE_DOUBLE
    static const int sig_digits = 9;
    static const UNITY_INT32 min_scaled = 100000000;
    static const UNITY_INT32 max_scaled = 1000000000;
#else
    static const int sig_digits = 7;
    static const UNITY_INT32 min_scaled = 1000000;
    static const UNITY_INT32 max_scaled = 10000000;
#endif

420
    UNITY_DOUBLE number = input_number;
421

422 423
    /* print minus sign (including for negative zero) */
    if (number < 0.0f || (number == 0.0f && 1.0f / number < 0.0f))
J
jsalling 已提交
424 425
    {
        UNITY_OUTPUT_CHAR('-');
426
        number = -number;
J
jsalling 已提交
427
    }
428

429
    /* handle zero, NaN, and +/- infinity */
K
Kochise 已提交
430 431 432 433 434 435 436 437 438 439 440 441
    if (number == 0.0f)
    {
        UnityPrint("0");
    }
    else if (isnan(number))
    {
        UnityPrint("nan");
    }
    else if (isinf(number))
    {
        UnityPrint("inf");
    }
442
    else
J
jsalling 已提交
443
    {
J
John Lindgren 已提交
444
        UNITY_INT32 n_int = 0, n;
445
        int exponent = 0;
J
John Lindgren 已提交
446
        int decimals, digits;
K
Kyle Krueger 已提交
447
        char buf[16] = {0};
448

449 450 451 452 453 454 455
        /*
         * Scale up or down by powers of 10.  To minimize rounding error,
         * start with a factor/divisor of 10^10, which is the largest
         * power of 10 that can be represented exactly.  Finally, compute
         * (exactly) the remaining power of 10 and perform one more
         * multiplication or division.
         */
456
        if (number < 1.0f)
457 458
        {
            UNITY_DOUBLE factor = 1.0f;
459

460 461
            while (number < (UNITY_DOUBLE)max_scaled / 1e10f) { number *= 1e10f; exponent -= 10; }
            while (number * factor < (UNITY_DOUBLE)min_scaled) { factor *= 10.0f; exponent--; }
462 463 464

            number *= factor;
        }
465
        else if (number > (UNITY_DOUBLE)max_scaled)
466 467 468
        {
            UNITY_DOUBLE divisor = 1.0f;

469 470
            while (number > (UNITY_DOUBLE)min_scaled * 1e10f) { number /= 1e10f; exponent += 10; }
            while (number / divisor > (UNITY_DOUBLE)max_scaled) { divisor *= 10.0f; exponent++; }
471 472 473

            number /= divisor;
        }
474 475 476 477 478 479 480 481
        else
        {
            /*
             * In this range, we can split off the integer part before
             * doing any multiplications.  This reduces rounding error by
             * freeing up significant bits in the fractional part.
             */
            UNITY_DOUBLE factor = 1.0f;
J
John Lindgren 已提交
482 483
            n_int = (UNITY_INT32)number;
            number -= (UNITY_DOUBLE)n_int;
484

J
John Lindgren 已提交
485
            while (n_int < min_scaled) { n_int *= 10; factor *= 10.0f; exponent--; }
486 487 488

            number *= factor;
        }
489 490

        /* round to nearest integer */
J
John Lindgren 已提交
491
        n = ((UNITY_INT32)(number + number) + 1) / 2;
J
John Lindgren 已提交
492 493 494 495 496 497 498 499 500

#ifndef UNITY_ROUND_TIES_AWAY_FROM_ZERO
        /* round to even if exactly between two integers */
        if ((n & 1) && ((UNITY_DOUBLE)n - number == 0.5f))
            n--;
#endif

        n += n_int;

501
        if (n >= max_scaled)
502
        {
503
            n = min_scaled;
504
            exponent++;
505 506
        }

507
        /* determine where to place decimal point */
508
        decimals = (exponent <= 0 && exponent >= -(sig_digits + 3)) ? -exponent : (sig_digits - 1);
509 510 511 512
        exponent += decimals;

        /* truncate trailing zeroes after decimal point */
        while (decimals > 0 && n % 10 == 0)
513
        {
514 515 516 517 518
            n /= 10;
            decimals--;
        }

        /* build up buffer in reverse order */
J
John Lindgren 已提交
519
        digits = 0;
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
        while (n != 0 || digits < decimals + 1)
        {
            buf[digits++] = (char)('0' + n % 10);
            n /= 10;
        }
        while (digits > 0)
        {
            if(digits == decimals) UNITY_OUTPUT_CHAR('.');
            UNITY_OUTPUT_CHAR(buf[--digits]);
        }

        /* print exponent if needed */
        if (exponent != 0)
        {
            UNITY_OUTPUT_CHAR('e');

            if(exponent < 0)
            {
                UNITY_OUTPUT_CHAR('-');
                exponent = -exponent;
            }
            else
            {
                UNITY_OUTPUT_CHAR('+');
            }

            digits = 0;
            while (exponent != 0 || digits < 2)
            {
                buf[digits++] = (char)('0' + exponent % 10);
                exponent /= 10;
            }
            while (digits > 0)
            {
                UNITY_OUTPUT_CHAR(buf[--digits]);
            }
556
        }
J
jsalling 已提交
557
    }
M
Mark VanderVoord 已提交
558
}
J
jsalling 已提交
559
#endif /* ! UNITY_EXCLUDE_FLOAT_PRINT */
M
Mark VanderVoord 已提交
560

561
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
562 563 564 565
static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line)
{
    UnityPrint(file);
    UNITY_OUTPUT_CHAR(':');
566
    UnityPrintNumber((UNITY_INT)line);
M
Mark VanderVoord 已提交
567 568 569 570 571
    UNITY_OUTPUT_CHAR(':');
    UnityPrint(Unity.CurrentTestName);
    UNITY_OUTPUT_CHAR(':');
}

572
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
573 574 575 576 577 578 579
static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line)
{
    UnityTestResultsBegin(Unity.TestFile, line);
    UnityPrint(UnityStrFail);
    UNITY_OUTPUT_CHAR(':');
}

580
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
void UnityConcludeTest(void)
{
    if (Unity.CurrentTestIgnored)
    {
        Unity.TestIgnores++;
    }
    else if (!Unity.CurrentTestFailed)
    {
        UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber);
        UnityPrint(UnityStrPass);
    }
    else
    {
        Unity.TestFailures++;
    }

    Unity.CurrentTestFailed = 0;
    Unity.CurrentTestIgnored = 0;
599
    UNITY_EXEC_TIME_RESET();
M
Mark VanderVoord 已提交
600
    UNITY_PRINT_EOL();
601
    UNITY_FLUSH_CALL();
M
Mark VanderVoord 已提交
602 603
}

604
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
static void UnityAddMsgIfSpecified(const char* msg)
{
    if (msg)
    {
        UnityPrint(UnityStrSpacer);
#ifndef UNITY_EXCLUDE_DETAILS
        if (Unity.CurrentDetail1)
        {
            UnityPrint(UnityStrDetail1Name);
            UnityPrint(Unity.CurrentDetail1);
            if (Unity.CurrentDetail2)
            {
                UnityPrint(UnityStrDetail2Name);
                UnityPrint(Unity.CurrentDetail2);
            }
            UnityPrint(UnityStrSpacer);
        }
#endif
        UnityPrint(msg);
    }
}

627
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
628 629 630 631 632 633 634 635 636 637 638
static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual)
{
    UnityPrint(UnityStrExpected);
    if (expected != NULL)
    {
        UNITY_OUTPUT_CHAR('\'');
        UnityPrint(expected);
        UNITY_OUTPUT_CHAR('\'');
    }
    else
    {
639
        UnityPrint(UnityStrNull);
M
Mark VanderVoord 已提交
640 641 642 643 644 645 646 647 648 649
    }
    UnityPrint(UnityStrWas);
    if (actual != NULL)
    {
        UNITY_OUTPUT_CHAR('\'');
        UnityPrint(actual);
        UNITY_OUTPUT_CHAR('\'');
    }
    else
    {
650
        UnityPrint(UnityStrNull);
M
Mark VanderVoord 已提交
651 652 653
    }
}

654
/*-----------------------------------------------*/
655 656 657
static void UnityPrintExpectedAndActualStringsLen(const char* expected,
                                                  const char* actual,
                                                  const UNITY_UINT32 length)
M
Mark VanderVoord 已提交
658 659 660 661 662 663 664 665 666 667
{
    UnityPrint(UnityStrExpected);
    if (expected != NULL)
    {
        UNITY_OUTPUT_CHAR('\'');
        UnityPrintLen(expected, length);
        UNITY_OUTPUT_CHAR('\'');
    }
    else
    {
668
        UnityPrint(UnityStrNull);
M
Mark VanderVoord 已提交
669 670 671 672 673 674 675 676 677 678
    }
    UnityPrint(UnityStrWas);
    if (actual != NULL)
    {
        UNITY_OUTPUT_CHAR('\'');
        UnityPrintLen(actual, length);
        UNITY_OUTPUT_CHAR('\'');
    }
    else
    {
679
        UnityPrint(UnityStrNull);
M
Mark VanderVoord 已提交
680 681 682
    }
}

683 684 685
/*-----------------------------------------------
 * Assertion & Control Helpers
 *-----------------------------------------------*/
M
Mark VanderVoord 已提交
686

K
Kochise 已提交
687
/*-----------------------------------------------*/
688 689 690 691
static int UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected,
                               UNITY_INTERNAL_PTR actual,
                               const UNITY_LINE_TYPE lineNumber,
                               const char* msg)
M
Mark VanderVoord 已提交
692
{
693
    if (expected == actual) return 0; /* Both are NULL or same pointer */
M
Mark VanderVoord 已提交
694

695
    /* print and return true if just expected is NULL */
M
Mark VanderVoord 已提交
696 697 698 699 700
    if (expected == NULL)
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrNullPointerForExpected);
        UnityAddMsgIfSpecified(msg);
701
        return 1;
M
Mark VanderVoord 已提交
702 703
    }

704
    /* print and return true if just actual is NULL */
M
Mark VanderVoord 已提交
705 706 707 708 709
    if (actual == NULL)
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrNullPointerForActual);
        UnityAddMsgIfSpecified(msg);
710
        return 1;
M
Mark VanderVoord 已提交
711 712
    }

713
    return 0; /* return false if neither is NULL */
M
Mark VanderVoord 已提交
714 715
}

716 717 718
/*-----------------------------------------------
 * Assertion Functions
 *-----------------------------------------------*/
M
Mark VanderVoord 已提交
719

K
Kochise 已提交
720
/*-----------------------------------------------*/
721 722 723
void UnityAssertBits(const UNITY_INT mask,
                     const UNITY_INT expected,
                     const UNITY_INT actual,
M
Mark VanderVoord 已提交
724 725 726
                     const char* msg,
                     const UNITY_LINE_TYPE lineNumber)
{
727
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
728 729 730 731 732

    if ((mask & expected) != (mask & actual))
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrExpected);
733
        UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)expected);
M
Mark VanderVoord 已提交
734
        UnityPrint(UnityStrWas);
735
        UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)actual);
M
Mark VanderVoord 已提交
736 737 738 739 740
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

741
/*-----------------------------------------------*/
742 743
void UnityAssertEqualNumber(const UNITY_INT expected,
                            const UNITY_INT actual,
M
Mark VanderVoord 已提交
744 745 746 747
                            const char* msg,
                            const UNITY_LINE_TYPE lineNumber,
                            const UNITY_DISPLAY_STYLE_T style)
{
748
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
749 750 751 752 753 754 755 756 757 758 759 760 761

    if (expected != actual)
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrExpected);
        UnityPrintNumberByStyle(expected, style);
        UnityPrint(UnityStrWas);
        UnityPrintNumberByStyle(actual, style);
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

762
/*-----------------------------------------------*/
763 764 765 766 767 768
void 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)
769
{
770
    int failed = 0;
771 772
    RETURN_IF_FAIL_OR_IGNORE;

773 774 775 776
    if (threshold == actual && compare & UNITY_EQUAL_TO) return;
    if (threshold == actual) failed = 1;

    if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
777
    {
778 779 780 781 782 783 784
        if (actual > threshold && compare & UNITY_SMALLER_THAN) failed = 1;
        if (actual < threshold && compare & UNITY_GREATER_THAN) failed = 1;
    }
    else /* UINT or HEX */
    {
        if ((UNITY_UINT)actual > (UNITY_UINT)threshold && compare & UNITY_SMALLER_THAN) failed = 1;
        if ((UNITY_UINT)actual < (UNITY_UINT)threshold && compare & UNITY_GREATER_THAN) failed = 1;
785 786
    }

787
    if (failed)
788 789 790 791
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrExpected);
        UnityPrintNumberByStyle(actual, style);
792 793 794
        if (compare & UNITY_GREATER_THAN) UnityPrint(UnityStrGt);
        if (compare & UNITY_SMALLER_THAN) UnityPrint(UnityStrLt);
        if (compare & UNITY_EQUAL_TO)     UnityPrint(UnityStrOrEqual);
795 796 797 798 799 800
        UnityPrintNumberByStyle(threshold, style);
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

801 802 803 804 805 806 807
#define UnityPrintPointlessAndBail()       \
{                                          \
    UnityTestResultsFailBegin(lineNumber); \
    UnityPrint(UnityStrPointless);         \
    UnityAddMsgIfSpecified(msg);           \
    UNITY_FAIL_AND_BAIL; }

808
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
809 810
void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
                              UNITY_INTERNAL_PTR actual,
811
                              const UNITY_UINT32 num_elements,
M
Mark VanderVoord 已提交
812 813
                              const char* msg,
                              const UNITY_LINE_TYPE lineNumber,
814 815
                              const UNITY_DISPLAY_STYLE_T style,
                              const UNITY_FLAGS_T flags)
M
Mark VanderVoord 已提交
816
{
817
    UNITY_UINT32 elements = num_elements;
818
    unsigned int length   = style & 0xF;
M
Mark VanderVoord 已提交
819

820
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
821

822 823 824 825
    if (num_elements == 0)
    {
        UnityPrintPointlessAndBail();
    }
M
Mark VanderVoord 已提交
826

K
Kochise 已提交
827 828 829 830 831
    if (expected == actual)
    {
        return; /* Both are NULL or same pointer */
    }

832
    if (UnityIsOneArrayNull(expected, actual, lineNumber, msg))
K
Kochise 已提交
833
    {
834
        UNITY_FAIL_AND_BAIL;
K
Kochise 已提交
835
    }
M
Mark VanderVoord 已提交
836

837
    while ((elements > 0) && elements--)
M
Mark VanderVoord 已提交
838
    {
839 840
        UNITY_INT expect_val;
        UNITY_INT actual_val;
841 842 843 844 845 846 847 848 849 850
        switch (length)
        {
            case 1:
                expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected;
                actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual;
                break;
            case 2:
                expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected;
                actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual;
                break;
M
Mark VanderVoord 已提交
851
#ifdef UNITY_SUPPORT_64
852 853 854 855
            case 8:
                expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected;
                actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual;
                break;
M
Mark VanderVoord 已提交
856
#endif
857 858 859 860 861
            default: /* length 4 bytes */
                expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected;
                actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual;
                length = 4;
                break;
862 863 864 865
        }

        if (expect_val != actual_val)
        {
866
            if (style & UNITY_DISPLAY_RANGE_UINT && length < sizeof(expect_val))
867 868 869 870 871 872
            {   /* For UINT, remove sign extension (padding 1's) from signed type casts above */
                UNITY_INT mask = 1;
                mask = (mask << 8 * length) - 1;
                expect_val &= mask;
                actual_val &= mask;
            }
873 874 875 876 877 878 879 880 881 882
            UnityTestResultsFailBegin(lineNumber);
            UnityPrint(UnityStrElement);
            UnityPrintNumberUnsigned(num_elements - elements - 1);
            UnityPrint(UnityStrExpected);
            UnityPrintNumberByStyle(expect_val, style);
            UnityPrint(UnityStrWas);
            UnityPrintNumberByStyle(actual_val, style);
            UnityAddMsgIfSpecified(msg);
            UNITY_FAIL_AND_BAIL;
        }
883 884 885 886
        if (flags == UNITY_ARRAY_TO_ARRAY)
        {
            expected = (UNITY_INTERNAL_PTR)(length + (const char*)expected);
        }
887
        actual   = (UNITY_INTERNAL_PTR)(length + (const char*)actual);
M
Mark VanderVoord 已提交
888 889 890
    }
}

891
/*-----------------------------------------------*/
892
#ifndef UNITY_EXCLUDE_FLOAT
893
/* Wrap this define in a function with variable types as float or double */
894 895 896 897 898 899 900
#define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff)                           \
    if (isinf(expected) && isinf(actual) && (((expected) < 0) == ((actual) < 0))) return 1;   \
    if (UNITY_NAN_CHECK) return 1;                                                            \
    (diff) = (actual) - (expected);                                                           \
    if ((diff) < 0) (diff) = -(diff);                                                         \
    if ((delta) < 0) (delta) = -(delta);                                                      \
    return !(isnan(diff) || isinf(diff) || ((diff) > (delta)))
901
    /* This first part of this condition will catch any NaN or Infinite values */
902 903 904 905 906
#ifndef UNITY_NAN_NOT_EQUAL_NAN
  #define UNITY_NAN_CHECK isnan(expected) && isnan(actual)
#else
  #define UNITY_NAN_CHECK 0
#endif
907

908 909
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
  #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \
910
  {                                                               \
911 912 913
    UnityPrint(UnityStrExpected);                                 \
    UnityPrintFloat(expected);                                    \
    UnityPrint(UnityStrWas);                                      \
914
    UnityPrintFloat(actual); }
915 916 917 918 919
#else
  #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \
    UnityPrint(UnityStrDelta)
#endif /* UNITY_EXCLUDE_FLOAT_PRINT */

K
Kochise 已提交
920
/*-----------------------------------------------*/
921
static int UnityFloatsWithin(UNITY_FLOAT delta, UNITY_FLOAT expected, UNITY_FLOAT actual)
922
{
923
    UNITY_FLOAT diff;
924 925 926
    UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff);
}

K
Kochise 已提交
927
/*-----------------------------------------------*/
928 929 930
void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected,
                                UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual,
                                const UNITY_UINT32 num_elements,
M
Mark VanderVoord 已提交
931
                                const char* msg,
932 933
                                const UNITY_LINE_TYPE lineNumber,
                                const UNITY_FLAGS_T flags)
M
Mark VanderVoord 已提交
934
{
935
    UNITY_UINT32 elements = num_elements;
936 937
    UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_expected = expected;
    UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_actual = actual;
M
Mark VanderVoord 已提交
938

939
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
940

941 942 943 944
    if (elements == 0)
    {
        UnityPrintPointlessAndBail();
    }
M
Mark VanderVoord 已提交
945

K
Kochise 已提交
946 947 948 949 950
    if (expected == actual)
    {
        return; /* Both are NULL or same pointer */
    }

951
    if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
K
Kochise 已提交
952
    {
953
        UNITY_FAIL_AND_BAIL;
K
Kochise 已提交
954
    }
M
Mark VanderVoord 已提交
955 956 957

    while (elements--)
    {
958
        if (!UnityFloatsWithin(*ptr_expected * UNITY_FLOAT_PRECISION, *ptr_expected, *ptr_actual))
M
Mark VanderVoord 已提交
959 960 961
        {
            UnityTestResultsFailBegin(lineNumber);
            UnityPrint(UnityStrElement);
962
            UnityPrintNumberUnsigned(num_elements - elements - 1);
963
            UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)*ptr_expected, (UNITY_DOUBLE)*ptr_actual);
M
Mark VanderVoord 已提交
964 965 966
            UnityAddMsgIfSpecified(msg);
            UNITY_FAIL_AND_BAIL;
        }
967 968 969 970
        if (flags == UNITY_ARRAY_TO_ARRAY)
        {
            ptr_expected++;
        }
971
        ptr_actual++;
M
Mark VanderVoord 已提交
972 973 974
    }
}

975
/*-----------------------------------------------*/
976 977 978
void UnityAssertFloatsWithin(const UNITY_FLOAT delta,
                             const UNITY_FLOAT expected,
                             const UNITY_FLOAT actual,
M
Mark VanderVoord 已提交
979 980 981
                             const char* msg,
                             const UNITY_LINE_TYPE lineNumber)
{
982
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
983 984


985
    if (!UnityFloatsWithin(delta, expected, actual))
M
Mark VanderVoord 已提交
986 987
    {
        UnityTestResultsFailBegin(lineNumber);
988
        UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual);
M
Mark VanderVoord 已提交
989 990 991 992 993
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

994
/*-----------------------------------------------*/
995
void UnityAssertFloatSpecial(const UNITY_FLOAT actual,
M
Mark VanderVoord 已提交
996 997 998 999
                             const char* msg,
                             const UNITY_LINE_TYPE lineNumber,
                             const UNITY_FLOAT_TRAIT_T style)
{
1000 1001 1002 1003
    const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet};
    UNITY_INT should_be_trait = ((UNITY_INT)style & 1);
    UNITY_INT is_trait        = !should_be_trait;
    UNITY_INT trait_index     = (UNITY_INT)(style >> 1);
M
Mark VanderVoord 已提交
1004

1005
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1006

1007
    switch (style)
M
Mark VanderVoord 已提交
1008 1009 1010
    {
        case UNITY_FLOAT_IS_INF:
        case UNITY_FLOAT_IS_NOT_INF:
1011
            is_trait = isinf(actual) && (actual > 0);
M
Mark VanderVoord 已提交
1012 1013 1014
            break;
        case UNITY_FLOAT_IS_NEG_INF:
        case UNITY_FLOAT_IS_NOT_NEG_INF:
1015
            is_trait = isinf(actual) && (actual < 0);
M
Mark VanderVoord 已提交
1016 1017 1018 1019
            break;

        case UNITY_FLOAT_IS_NAN:
        case UNITY_FLOAT_IS_NOT_NAN:
1020
            is_trait = isnan(actual) ? 1 : 0;
M
Mark VanderVoord 已提交
1021 1022
            break;

1023
        case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */
M
Mark VanderVoord 已提交
1024
        case UNITY_FLOAT_IS_NOT_DET:
1025
            is_trait = !isinf(actual) && !isnan(actual);
M
Mark VanderVoord 已提交
1026 1027 1028
            break;

        default:
1029 1030 1031
            trait_index = 0;
            trait_names[0] = UnityStrInvalidFloatTrait;
            break;
M
Mark VanderVoord 已提交
1032 1033 1034 1035 1036 1037 1038
    }

    if (is_trait != should_be_trait)
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrExpected);
        if (!should_be_trait)
K
Kochise 已提交
1039
        {
M
Mark VanderVoord 已提交
1040
            UnityPrint(UnityStrNot);
K
Kochise 已提交
1041
        }
M
Mark VanderVoord 已提交
1042 1043
        UnityPrint(trait_names[trait_index]);
        UnityPrint(UnityStrWas);
J
jsalling 已提交
1044
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
1045
        UnityPrintFloat((UNITY_DOUBLE)actual);
M
Mark VanderVoord 已提交
1046 1047
#else
        if (should_be_trait)
K
Kochise 已提交
1048
        {
M
Mark VanderVoord 已提交
1049
            UnityPrint(UnityStrNot);
K
Kochise 已提交
1050
        }
M
Mark VanderVoord 已提交
1051 1052 1053 1054 1055 1056 1057
        UnityPrint(trait_names[trait_index]);
#endif
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

1058
#endif /* not UNITY_EXCLUDE_FLOAT */
M
Mark VanderVoord 已提交
1059

1060
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1061
#ifndef UNITY_EXCLUDE_DOUBLE
1062
static int UnityDoublesWithin(UNITY_DOUBLE delta, UNITY_DOUBLE expected, UNITY_DOUBLE actual)
1063
{
1064
    UNITY_DOUBLE diff;
1065 1066 1067
    UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff);
}

K
Kochise 已提交
1068
/*-----------------------------------------------*/
1069 1070 1071
void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected,
                                 UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual,
                                 const UNITY_UINT32 num_elements,
M
Mark VanderVoord 已提交
1072
                                 const char* msg,
1073 1074
                                 const UNITY_LINE_TYPE lineNumber,
                                 const UNITY_FLAGS_T flags)
M
Mark VanderVoord 已提交
1075
{
1076
    UNITY_UINT32 elements = num_elements;
1077 1078
    UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_expected = expected;
    UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_actual = actual;
M
Mark VanderVoord 已提交
1079

1080
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1081

1082 1083 1084 1085
    if (elements == 0)
    {
        UnityPrintPointlessAndBail();
    }
M
Mark VanderVoord 已提交
1086

K
Kochise 已提交
1087 1088 1089 1090 1091
    if (expected == actual)
    {
        return; /* Both are NULL or same pointer */
    }

1092
    if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
K
Kochise 已提交
1093
    {
1094
        UNITY_FAIL_AND_BAIL;
K
Kochise 已提交
1095
    }
M
Mark VanderVoord 已提交
1096 1097 1098

    while (elements--)
    {
1099
        if (!UnityDoublesWithin(*ptr_expected * UNITY_DOUBLE_PRECISION, *ptr_expected, *ptr_actual))
M
Mark VanderVoord 已提交
1100 1101 1102
        {
            UnityTestResultsFailBegin(lineNumber);
            UnityPrint(UnityStrElement);
1103
            UnityPrintNumberUnsigned(num_elements - elements - 1);
1104
            UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(*ptr_expected, *ptr_actual);
M
Mark VanderVoord 已提交
1105 1106 1107
            UnityAddMsgIfSpecified(msg);
            UNITY_FAIL_AND_BAIL;
        }
1108 1109 1110 1111
        if (flags == UNITY_ARRAY_TO_ARRAY)
        {
            ptr_expected++;
        }
1112
        ptr_actual++;
M
Mark VanderVoord 已提交
1113 1114 1115
    }
}

1116
/*-----------------------------------------------*/
1117 1118 1119
void UnityAssertDoublesWithin(const UNITY_DOUBLE delta,
                              const UNITY_DOUBLE expected,
                              const UNITY_DOUBLE actual,
M
Mark VanderVoord 已提交
1120 1121 1122
                              const char* msg,
                              const UNITY_LINE_TYPE lineNumber)
{
1123
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1124

1125
    if (!UnityDoublesWithin(delta, expected, actual))
M
Mark VanderVoord 已提交
1126 1127
    {
        UnityTestResultsFailBegin(lineNumber);
1128
        UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual);
M
Mark VanderVoord 已提交
1129 1130 1131 1132 1133
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

1134
/*-----------------------------------------------*/
1135
void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual,
M
Mark VanderVoord 已提交
1136 1137 1138 1139
                              const char* msg,
                              const UNITY_LINE_TYPE lineNumber,
                              const UNITY_FLOAT_TRAIT_T style)
{
1140 1141 1142 1143
    const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet};
    UNITY_INT should_be_trait = ((UNITY_INT)style & 1);
    UNITY_INT is_trait        = !should_be_trait;
    UNITY_INT trait_index     = (UNITY_INT)(style >> 1);
M
Mark VanderVoord 已提交
1144

1145
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1146

1147
    switch (style)
M
Mark VanderVoord 已提交
1148 1149 1150
    {
        case UNITY_FLOAT_IS_INF:
        case UNITY_FLOAT_IS_NOT_INF:
1151
            is_trait = isinf(actual) && (actual > 0);
M
Mark VanderVoord 已提交
1152 1153 1154
            break;
        case UNITY_FLOAT_IS_NEG_INF:
        case UNITY_FLOAT_IS_NOT_NEG_INF:
1155
            is_trait = isinf(actual) && (actual < 0);
M
Mark VanderVoord 已提交
1156 1157 1158 1159
            break;

        case UNITY_FLOAT_IS_NAN:
        case UNITY_FLOAT_IS_NOT_NAN:
1160
            is_trait = isnan(actual) ? 1 : 0;
M
Mark VanderVoord 已提交
1161 1162
            break;

1163
        case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */
M
Mark VanderVoord 已提交
1164
        case UNITY_FLOAT_IS_NOT_DET:
1165
            is_trait = !isinf(actual) && !isnan(actual);
M
Mark VanderVoord 已提交
1166 1167 1168
            break;

        default:
1169 1170 1171
            trait_index = 0;
            trait_names[0] = UnityStrInvalidFloatTrait;
            break;
M
Mark VanderVoord 已提交
1172 1173 1174 1175 1176 1177 1178
    }

    if (is_trait != should_be_trait)
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrExpected);
        if (!should_be_trait)
K
Kochise 已提交
1179
        {
M
Mark VanderVoord 已提交
1180
            UnityPrint(UnityStrNot);
K
Kochise 已提交
1181
        }
M
Mark VanderVoord 已提交
1182 1183
        UnityPrint(trait_names[trait_index]);
        UnityPrint(UnityStrWas);
J
jsalling 已提交
1184
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
M
Mark VanderVoord 已提交
1185 1186 1187
        UnityPrintFloat(actual);
#else
        if (should_be_trait)
K
Kochise 已提交
1188
        {
M
Mark VanderVoord 已提交
1189
            UnityPrint(UnityStrNot);
K
Kochise 已提交
1190
        }
M
Mark VanderVoord 已提交
1191 1192 1193 1194 1195 1196 1197
        UnityPrint(trait_names[trait_index]);
#endif
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

1198
#endif /* not UNITY_EXCLUDE_DOUBLE */
M
Mark VanderVoord 已提交
1199

1200
/*-----------------------------------------------*/
1201 1202 1203 1204 1205 1206
void 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)
M
Mark VanderVoord 已提交
1207
{
1208
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1209 1210 1211 1212

    if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
    {
        if (actual > expected)
K
Kochise 已提交
1213
        {
1214
            Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta);
K
Kochise 已提交
1215
        }
M
Mark VanderVoord 已提交
1216
        else
K
Kochise 已提交
1217
        {
1218
            Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta);
K
Kochise 已提交
1219
        }
M
Mark VanderVoord 已提交
1220 1221 1222
    }
    else
    {
1223
        if ((UNITY_UINT)actual > (UNITY_UINT)expected)
K
Kochise 已提交
1224
        {
1225
            Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta);
K
Kochise 已提交
1226
        }
M
Mark VanderVoord 已提交
1227
        else
K
Kochise 已提交
1228
        {
1229
            Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta);
K
Kochise 已提交
1230
        }
M
Mark VanderVoord 已提交
1231 1232 1233 1234 1235 1236
    }

    if (Unity.CurrentTestFailed)
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrDelta);
1237
        UnityPrintNumberByStyle((UNITY_INT)delta, style);
M
Mark VanderVoord 已提交
1238 1239 1240 1241 1242 1243 1244 1245 1246
        UnityPrint(UnityStrExpected);
        UnityPrintNumberByStyle(expected, style);
        UnityPrint(UnityStrWas);
        UnityPrintNumberByStyle(actual, style);
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

1247
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1248 1249 1250 1251 1252
void UnityAssertEqualString(const char* expected,
                            const char* actual,
                            const char* msg,
                            const UNITY_LINE_TYPE lineNumber)
{
1253
    UNITY_UINT32 i;
M
Mark VanderVoord 已提交
1254

1255
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1256

1257
    /* if both pointers not null compare the strings */
M
Mark VanderVoord 已提交
1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269
    if (expected && actual)
    {
        for (i = 0; expected[i] || actual[i]; i++)
        {
            if (expected[i] != actual[i])
            {
                Unity.CurrentTestFailed = 1;
                break;
            }
        }
    }
    else
1270
    { /* handle case of one pointers being null (if both null, test should pass) */
M
Mark VanderVoord 已提交
1271 1272 1273 1274 1275 1276 1277 1278
        if (expected != actual)
        {
            Unity.CurrentTestFailed = 1;
        }
    }

    if (Unity.CurrentTestFailed)
    {
1279 1280 1281 1282
        UnityTestResultsFailBegin(lineNumber);
        UnityPrintExpectedAndActualStrings(expected, actual);
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
M
Mark VanderVoord 已提交
1283 1284 1285
    }
}

1286
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1287
void UnityAssertEqualStringLen(const char* expected,
1288 1289 1290 1291
                               const char* actual,
                               const UNITY_UINT32 length,
                               const char* msg,
                               const UNITY_LINE_TYPE lineNumber)
M
Mark VanderVoord 已提交
1292
{
1293
    UNITY_UINT32 i;
M
Mark VanderVoord 已提交
1294

1295
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1296

1297
    /* if both pointers not null compare the strings */
M
Mark VanderVoord 已提交
1298 1299
    if (expected && actual)
    {
1300
        for (i = 0; (i < length) && (expected[i] || actual[i]); i++)
M
Mark VanderVoord 已提交
1301 1302 1303 1304 1305 1306 1307 1308 1309
        {
            if (expected[i] != actual[i])
            {
                Unity.CurrentTestFailed = 1;
                break;
            }
        }
    }
    else
1310
    { /* handle case of one pointers being null (if both null, test should pass) */
M
Mark VanderVoord 已提交
1311 1312 1313 1314 1315 1316 1317 1318
        if (expected != actual)
        {
            Unity.CurrentTestFailed = 1;
        }
    }

    if (Unity.CurrentTestFailed)
    {
1319 1320 1321 1322
        UnityTestResultsFailBegin(lineNumber);
        UnityPrintExpectedAndActualStringsLen(expected, actual, length);
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
M
Mark VanderVoord 已提交
1323 1324 1325
    }
}

1326
/*-----------------------------------------------*/
1327
void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
1328 1329 1330
                                 const char** actual,
                                 const UNITY_UINT32 num_elements,
                                 const char* msg,
1331 1332
                                 const UNITY_LINE_TYPE lineNumber,
                                 const UNITY_FLAGS_T flags)
M
Mark VanderVoord 已提交
1333
{
1334 1335
    UNITY_UINT32 i = 0;
    UNITY_UINT32 j = 0;
1336
    const char* expd = NULL;
1337
    const char* act = NULL;
M
Mark VanderVoord 已提交
1338

1339
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1340

1341
    /* if no elements, it's an error */
1342 1343 1344 1345
    if (num_elements == 0)
    {
        UnityPrintPointlessAndBail();
    }
M
Mark VanderVoord 已提交
1346

1347
    if ((const void*)expected == (const void*)actual)
1348 1349 1350 1351
    {
        return; /* Both are NULL or same pointer */
    }

1352
    if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
1353
    {
1354
        UNITY_FAIL_AND_BAIL;
1355 1356 1357 1358
    }

    if (flags != UNITY_ARRAY_TO_ARRAY)
    {
1359
        expd = (const char*)expected;
1360
    }
M
Mark VanderVoord 已提交
1361 1362 1363

    do
    {
1364 1365 1366
        act = actual[j];
        if (flags == UNITY_ARRAY_TO_ARRAY)
        {
1367
            expd = ((const char* const*)expected)[j];
1368 1369
        }

1370
        /* if both pointers not null compare the strings */
1371
        if (expd && act)
M
Mark VanderVoord 已提交
1372
        {
1373
            for (i = 0; expd[i] || act[i]; i++)
M
Mark VanderVoord 已提交
1374
            {
1375
                if (expd[i] != act[i])
M
Mark VanderVoord 已提交
1376 1377 1378 1379 1380 1381 1382
                {
                    Unity.CurrentTestFailed = 1;
                    break;
                }
            }
        }
        else
1383
        { /* handle case of one pointers being null (if both null, test should pass) */
1384
            if (expd != act)
M
Mark VanderVoord 已提交
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395
            {
                Unity.CurrentTestFailed = 1;
            }
        }

        if (Unity.CurrentTestFailed)
        {
            UnityTestResultsFailBegin(lineNumber);
            if (num_elements > 1)
            {
                UnityPrint(UnityStrElement);
1396
                UnityPrintNumberUnsigned(j);
M
Mark VanderVoord 已提交
1397
            }
1398
            UnityPrintExpectedAndActualStrings(expd, act);
M
Mark VanderVoord 已提交
1399 1400 1401 1402 1403 1404
            UnityAddMsgIfSpecified(msg);
            UNITY_FAIL_AND_BAIL;
        }
    } while (++j < num_elements);
}

1405
/*-----------------------------------------------*/
1406 1407 1408 1409 1410
void UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected,
                            UNITY_INTERNAL_PTR actual,
                            const UNITY_UINT32 length,
                            const UNITY_UINT32 num_elements,
                            const char* msg,
1411 1412
                            const UNITY_LINE_TYPE lineNumber,
                            const UNITY_FLAGS_T flags)
M
Mark VanderVoord 已提交
1413 1414 1415
{
    UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected;
    UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual;
1416 1417
    UNITY_UINT32 elements = num_elements;
    UNITY_UINT32 bytes;
M
Mark VanderVoord 已提交
1418

1419
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1420

1421 1422 1423 1424
    if ((elements == 0) || (length == 0))
    {
        UnityPrintPointlessAndBail();
    }
M
Mark VanderVoord 已提交
1425

K
Kochise 已提交
1426 1427 1428 1429 1430
    if (expected == actual)
    {
        return; /* Both are NULL or same pointer */
    }

1431
    if (UnityIsOneArrayNull(expected, actual, lineNumber, msg))
K
Kochise 已提交
1432
    {
1433
        UNITY_FAIL_AND_BAIL;
K
Kochise 已提交
1434
    }
M
Mark VanderVoord 已提交
1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447

    while (elements--)
    {
        bytes = length;
        while (bytes--)
        {
            if (*ptr_exp != *ptr_act)
            {
                UnityTestResultsFailBegin(lineNumber);
                UnityPrint(UnityStrMemory);
                if (num_elements > 1)
                {
                    UnityPrint(UnityStrElement);
1448
                    UnityPrintNumberUnsigned(num_elements - elements - 1);
M
Mark VanderVoord 已提交
1449 1450
                }
                UnityPrint(UnityStrByte);
1451
                UnityPrintNumberUnsigned(length - bytes - 1);
M
Mark VanderVoord 已提交
1452 1453 1454 1455 1456 1457 1458
                UnityPrint(UnityStrExpected);
                UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8);
                UnityPrint(UnityStrWas);
                UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8);
                UnityAddMsgIfSpecified(msg);
                UNITY_FAIL_AND_BAIL;
            }
1459 1460
            ptr_exp++;
            ptr_act++;
M
Mark VanderVoord 已提交
1461
        }
1462 1463 1464 1465
        if (flags == UNITY_ARRAY_TO_VAL)
        {
            ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected;
        }
M
Mark VanderVoord 已提交
1466 1467 1468
    }
}

1469 1470 1471 1472 1473 1474 1475 1476 1477 1478
/*-----------------------------------------------*/

static union
{
    UNITY_INT8 i8;
    UNITY_INT16 i16;
    UNITY_INT32 i32;
#ifdef UNITY_SUPPORT_64
    UNITY_INT64 i64;
#endif
1479 1480 1481 1482 1483 1484
#ifndef UNITY_EXCLUDE_FLOAT
    float f;
#endif
#ifndef UNITY_EXCLUDE_DOUBLE
    double d;
#endif
1485 1486 1487 1488 1489 1490 1491
} UnityQuickCompare;

UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size)
{
    switch(size)
    {
        case 1:
1492
          UnityQuickCompare.i8 = (UNITY_INT8)num;
1493 1494 1495
          return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i8);

        case 2:
1496
          UnityQuickCompare.i16 = (UNITY_INT16)num;
1497 1498 1499 1500
          return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i16);

#ifdef UNITY_SUPPORT_64
        case 8:
1501
          UnityQuickCompare.i64 = (UNITY_INT64)num;
1502 1503
          return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i64);
#endif
1504
        default: /* 4 bytes */
1505
          UnityQuickCompare.i32 = (UNITY_INT32)num;
1506 1507 1508 1509
          return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i32);
    }
}

1510
#ifndef UNITY_EXCLUDE_FLOAT
K
Kochise 已提交
1511
/*-----------------------------------------------*/
1512 1513 1514 1515 1516 1517 1518 1519
UNITY_INTERNAL_PTR UnityFloatToPtr(const float num)
{
    UnityQuickCompare.f = num;
    return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.f);
}
#endif

#ifndef UNITY_EXCLUDE_DOUBLE
K
Kochise 已提交
1520
/*-----------------------------------------------*/
1521 1522 1523 1524 1525 1526 1527
UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num)
{
    UnityQuickCompare.d = num;
    return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.d);
}
#endif

1528 1529 1530
/*-----------------------------------------------
 * Control Functions
 *-----------------------------------------------*/
M
Mark VanderVoord 已提交
1531

K
Kochise 已提交
1532
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1533 1534
void UnityFail(const char* msg, const UNITY_LINE_TYPE line)
{
1535
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1536 1537

    UnityTestResultsBegin(Unity.TestFile, line);
1538
    UnityPrint(UnityStrFail);
M
Mark VanderVoord 已提交
1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565
    if (msg != NULL)
    {
        UNITY_OUTPUT_CHAR(':');

#ifndef UNITY_EXCLUDE_DETAILS
        if (Unity.CurrentDetail1)
        {
            UnityPrint(UnityStrDetail1Name);
            UnityPrint(Unity.CurrentDetail1);
            if (Unity.CurrentDetail2)
            {
                UnityPrint(UnityStrDetail2Name);
                UnityPrint(Unity.CurrentDetail2);
            }
            UnityPrint(UnityStrSpacer);
        }
#endif
        if (msg[0] != ' ')
        {
            UNITY_OUTPUT_CHAR(' ');
        }
        UnityPrint(msg);
    }

    UNITY_FAIL_AND_BAIL;
}

1566
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1567 1568
void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line)
{
1569
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1570 1571 1572 1573 1574

    UnityTestResultsBegin(Unity.TestFile, line);
    UnityPrint(UnityStrIgnore);
    if (msg != NULL)
    {
1575 1576 1577
        UNITY_OUTPUT_CHAR(':');
        UNITY_OUTPUT_CHAR(' ');
        UnityPrint(msg);
M
Mark VanderVoord 已提交
1578 1579 1580 1581
    }
    UNITY_IGNORE_AND_BAIL;
}

1582
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593
void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum)
{
    Unity.CurrentTestName = FuncName;
    Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum;
    Unity.NumberOfTests++;
    UNITY_CLR_DETAILS();
    if (TEST_PROTECT())
    {
        setUp();
        Func();
    }
1594
    if (TEST_PROTECT())
M
Mark VanderVoord 已提交
1595 1596 1597 1598 1599 1600
    {
        tearDown();
    }
    UnityConcludeTest();
}

1601
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1602 1603 1604 1605 1606 1607 1608 1609 1610 1611
void UnityBegin(const char* filename)
{
    Unity.TestFile = filename;
    Unity.CurrentTestName = NULL;
    Unity.CurrentTestLineNumber = 0;
    Unity.NumberOfTests = 0;
    Unity.TestFailures = 0;
    Unity.TestIgnores = 0;
    Unity.CurrentTestFailed = 0;
    Unity.CurrentTestIgnored = 0;
1612
    UNITY_EXEC_TIME_RESET();
M
Mark VanderVoord 已提交
1613 1614 1615 1616 1617

    UNITY_CLR_DETAILS();
    UNITY_OUTPUT_START();
}

1618
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1619 1620 1621 1622 1623
int UnityEnd(void)
{
    UNITY_PRINT_EOL();
    UnityPrint(UnityStrBreaker);
    UNITY_PRINT_EOL();
1624
    UnityPrintNumber((UNITY_INT)(Unity.NumberOfTests));
M
Mark VanderVoord 已提交
1625
    UnityPrint(UnityStrResultsTests);
1626
    UnityPrintNumber((UNITY_INT)(Unity.TestFailures));
M
Mark VanderVoord 已提交
1627
    UnityPrint(UnityStrResultsFailures);
1628
    UnityPrintNumber((UNITY_INT)(Unity.TestIgnores));
M
Mark VanderVoord 已提交
1629 1630 1631 1632
    UnityPrint(UnityStrResultsIgnored);
    UNITY_PRINT_EOL();
    if (Unity.TestFailures == 0U)
    {
1633
        UnityPrint(UnityStrOk);
M
Mark VanderVoord 已提交
1634 1635 1636
    }
    else
    {
1637
        UnityPrint(UnityStrFail);
1638 1639 1640
#ifdef UNITY_DIFFERENTIATE_FINAL_FAIL
        UNITY_OUTPUT_CHAR('E'); UNITY_OUTPUT_CHAR('D');
#endif
M
Mark VanderVoord 已提交
1641 1642
    }
    UNITY_PRINT_EOL();
1643
    UNITY_FLUSH_CALL();
M
Mark VanderVoord 已提交
1644 1645 1646 1647
    UNITY_OUTPUT_COMPLETE();
    return (int)(Unity.TestFailures);
}

1648 1649 1650
/*-----------------------------------------------
 * Command Line Argument Support
 *-----------------------------------------------*/
1651
#ifdef UNITY_USE_COMMAND_LINE_ARGS
1652 1653 1654

char* UnityOptionIncludeNamed = NULL;
char* UnityOptionExcludeNamed = NULL;
1655
int UnityVerbosity            = 1;
1656

K
Kochise 已提交
1657
/*-----------------------------------------------*/
1658 1659 1660 1661 1662 1663 1664 1665 1666
int UnityParseOptions(int argc, char** argv)
{
    UnityOptionIncludeNamed = NULL;
    UnityOptionExcludeNamed = NULL;

    for (int i = 1; i < argc; i++)
    {
        if (argv[i][0] == '-')
        {
1667
            switch (argv[i][1])
1668 1669
            {
                case 'l': /* list tests */
1670
                    return -1;
1671
                case 'n': /* include tests with name including this string */
1672 1673
                case 'f': /* an alias for -n */
                    if (argv[i][2] == '=')
K
Kochise 已提交
1674
                    {
1675
                        UnityOptionIncludeNamed = &argv[i][3];
K
Kochise 已提交
1676
                    }
1677
                    else if (++i < argc)
K
Kochise 已提交
1678
                    {
1679
                        UnityOptionIncludeNamed = argv[i];
K
Kochise 已提交
1680
                    }
1681 1682 1683 1684
                    else
                    {
                        UnityPrint("ERROR: No Test String to Include Matches For");
                        UNITY_PRINT_EOL();
1685
                        return 1;
1686 1687 1688 1689 1690 1691 1692 1693 1694
                    }
                    break;
                case 'q': /* quiet */
                    UnityVerbosity = 0;
                    break;
                case 'v': /* verbose */
                    UnityVerbosity = 2;
                    break;
                case 'x': /* exclude tests with name including this string */
1695
                    if (argv[i][2] == '=')
K
Kochise 已提交
1696
                    {
1697
                        UnityOptionExcludeNamed = &argv[i][3];
K
Kochise 已提交
1698
                    }
1699
                    else if (++i < argc)
K
Kochise 已提交
1700
                    {
1701
                        UnityOptionExcludeNamed = argv[i];
K
Kochise 已提交
1702
                    }
1703 1704 1705 1706
                    else
                    {
                        UnityPrint("ERROR: No Test String to Exclude Matches For");
                        UNITY_PRINT_EOL();
1707
                        return 1;
1708 1709 1710 1711
                    }
                    break;
                default:
                    UnityPrint("ERROR: Unknown Option ");
1712
                    UNITY_OUTPUT_CHAR(argv[i][1]);
1713 1714 1715 1716 1717 1718 1719 1720 1721
                    UNITY_PRINT_EOL();
                    return 1;
            }
        }
    }

    return 0;
}

K
Kochise 已提交
1722
/*-----------------------------------------------*/
1723
int IsStringInBiggerString(const char* longstring, const char* shortstring)
1724
{
1725 1726 1727
    const char* lptr = longstring;
    const char* sptr = shortstring;
    const char* lnext = lptr;
1728

1729
    if (*sptr == '*')
K
Kochise 已提交
1730
    {
1731
        return 1;
K
Kochise 已提交
1732
    }
1733

1734 1735 1736
    while (*lptr)
    {
        lnext = lptr + 1;
1737

1738 1739 1740 1741 1742
        /* If they current bytes match, go on to the next bytes */
        while (*lptr && *sptr && (*lptr == *sptr))
        {
            lptr++;
            sptr++;
1743

1744 1745 1746
            /* We're done if we match the entire string or up to a wildcard */
            if (*sptr == '*')
                return 1;
1747 1748 1749 1750 1751 1752 1753 1754
            if (*sptr == ',')
                return 1;
            if (*sptr == '"')
                return 1;
            if (*sptr == '\'')
                return 1;
            if (*sptr == ':')
                return 2;
1755 1756 1757 1758 1759 1760
            if (*sptr == 0)
                return 1;
        }

        /* Otherwise we start in the long pointer 1 character further and try again */
        lptr = lnext;
1761
        sptr = shortstring;
1762
    }
K
Kochise 已提交
1763

1764
    return 0;
1765 1766
}

K
Kochise 已提交
1767
/*-----------------------------------------------*/
1768 1769
int UnityStringArgumentMatches(const char* str)
{
1770 1771 1772
    int retval;
    const char* ptr1;
    const char* ptr2;
1773
    const char* ptrf;
1774

1775
    /* Go through the options and get the substrings for matching one at a time */
1776 1777 1778 1779
    ptr1 = str;
    while (ptr1[0] != 0)
    {
        if ((ptr1[0] == '"') || (ptr1[0] == '\''))
K
Kochise 已提交
1780
        {
1781
            ptr1++;
K
Kochise 已提交
1782
        }
1783

1784
        /* look for the start of the next partial */
1785
        ptr2 = ptr1;
1786
        ptrf = 0;
1787 1788
        do
        {
1789
            ptr2++;
1790
            if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ','))
K
Kochise 已提交
1791
            {
1792
                ptrf = &ptr2[1];
K
Kochise 已提交
1793
            }
1794
        } while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ','));
K
Kochise 已提交
1795

1796
        while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ',')))
K
Kochise 已提交
1797
        {
1798
            ptr2++;
K
Kochise 已提交
1799
        }
1800

1801
        /* done if complete filename match */
1802 1803
        retval = IsStringInBiggerString(Unity.TestFile, ptr1);
        if (retval == 1)
K
Kochise 已提交
1804
        {
1805
            return retval;
K
Kochise 已提交
1806
        }
1807

1808
        /* done if testname match after filename partial match */
1809
        if ((retval == 2) && (ptrf != 0))
1810
        {
1811
            if (IsStringInBiggerString(Unity.CurrentTestName, ptrf))
K
Kochise 已提交
1812
            {
1813
                return 1;
K
Kochise 已提交
1814
            }
1815 1816
        }

1817
        /* done if complete testname match */
1818
        if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1)
K
Kochise 已提交
1819
        {
1820
            return 1;
K
Kochise 已提交
1821
        }
1822 1823 1824 1825

        ptr1 = ptr2;
    }

1826
    /* we couldn't find a match for any substrings */
1827
    return 0;
1828
}
1829

K
Kochise 已提交
1830
/*-----------------------------------------------*/
1831 1832 1833 1834 1835 1836 1837 1838 1839
int UnityTestMatches(void)
{
    /* Check if this test name matches the included test pattern */
    int retval;
    if (UnityOptionIncludeNamed)
    {
        retval = UnityStringArgumentMatches(UnityOptionIncludeNamed);
    }
    else
K
Kochise 已提交
1840
    {
1841
        retval = 1;
K
Kochise 已提交
1842
    }
1843

1844 1845 1846 1847
    /* Check if this test name matches the excluded test pattern */
    if (UnityOptionExcludeNamed)
    {
        if (UnityStringArgumentMatches(UnityOptionExcludeNamed))
K
Kochise 已提交
1848
        {
1849
            retval = 0;
K
Kochise 已提交
1850
        }
1851
    }
K
Kochise 已提交
1852

1853
    return retval;
1854 1855
}

1856
#endif /* UNITY_USE_COMMAND_LINE_ARGS */
1857
/*-----------------------------------------------*/