unity.c 48.3 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 70 71 72 73 74 75 76 77

void UnityPrint(const char* string)
{
    const char* pch = string;

    if (pch != NULL)
    {
        while (*pch)
        {
78
            /* printable characters plus CR & LF are printed */
M
Mark VanderVoord 已提交
79 80 81 82
            if ((*pch <= 126) && (*pch >= 32))
            {
                UNITY_OUTPUT_CHAR(*pch);
            }
83
            /* write escaped carriage returns */
M
Mark VanderVoord 已提交
84 85 86 87 88
            else if (*pch == 13)
            {
                UNITY_OUTPUT_CHAR('\\');
                UNITY_OUTPUT_CHAR('r');
            }
89
            /* write escaped line feeds */
M
Mark VanderVoord 已提交
90 91 92 93 94
            else if (*pch == 10)
            {
                UNITY_OUTPUT_CHAR('\\');
                UNITY_OUTPUT_CHAR('n');
            }
95 96 97 98 99 100 101 102 103 104 105 106
#ifdef UNITY_OUTPUT_COLOR
            /* print ANSI escape code */
            else if (*pch == 27 && *(pch + 1) == '[')
            {
                while (*pch && *pch != 'm')
                {
                    UNITY_OUTPUT_CHAR(*pch);
                    pch++;
                }
                UNITY_OUTPUT_CHAR('m');
            }
#endif
107
            /* unprintable characters are shown as codes */
M
Mark VanderVoord 已提交
108 109 110
            else
            {
                UNITY_OUTPUT_CHAR('\\');
111
                UNITY_OUTPUT_CHAR('x');
112
                UnityPrintNumberHex((UNITY_UINT)*pch, 2);
M
Mark VanderVoord 已提交
113 114 115 116 117 118
            }
            pch++;
        }
    }
}

119
void UnityPrintLen(const char* string, const UNITY_UINT32 length)
M
Mark VanderVoord 已提交
120 121 122 123 124
{
    const char* pch = string;

    if (pch != NULL)
    {
125
        while (*pch && (UNITY_UINT32)(pch - string) < length)
M
Mark VanderVoord 已提交
126
        {
127
            /* printable characters plus CR & LF are printed */
M
Mark VanderVoord 已提交
128 129 130 131
            if ((*pch <= 126) && (*pch >= 32))
            {
                UNITY_OUTPUT_CHAR(*pch);
            }
132
            /* write escaped carriage returns */
M
Mark VanderVoord 已提交
133 134 135 136 137
            else if (*pch == 13)
            {
                UNITY_OUTPUT_CHAR('\\');
                UNITY_OUTPUT_CHAR('r');
            }
138
            /* write escaped line feeds */
M
Mark VanderVoord 已提交
139 140 141 142 143
            else if (*pch == 10)
            {
                UNITY_OUTPUT_CHAR('\\');
                UNITY_OUTPUT_CHAR('n');
            }
144
            /* unprintable characters are shown as codes */
M
Mark VanderVoord 已提交
145 146 147
            else
            {
                UNITY_OUTPUT_CHAR('\\');
148
                UNITY_OUTPUT_CHAR('x');
149
                UnityPrintNumberHex((UNITY_UINT)*pch, 2);
M
Mark VanderVoord 已提交
150 151 152 153 154 155
            }
            pch++;
        }
    }
}

156
/*-----------------------------------------------*/
157
void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style)
M
Mark VanderVoord 已提交
158 159 160 161 162 163 164
{
    if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
    {
        UnityPrintNumber(number);
    }
    else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT)
    {
165
        UnityPrintNumberUnsigned((UNITY_UINT)number);
M
Mark VanderVoord 已提交
166 167 168
    }
    else
    {
169 170
        UNITY_OUTPUT_CHAR('0');
        UNITY_OUTPUT_CHAR('x');
171
        UnityPrintNumberHex((UNITY_UINT)number, (char)((style & 0xF) * 2));
M
Mark VanderVoord 已提交
172 173 174
    }
}

175
/*-----------------------------------------------*/
176
void UnityPrintNumber(const UNITY_INT number_to_print)
M
Mark VanderVoord 已提交
177
{
178
    UNITY_UINT number = (UNITY_UINT)number_to_print;
M
Mark VanderVoord 已提交
179 180 181

    if (number_to_print < 0)
    {
182
        /* A negative number, including MIN negative */
M
Mark VanderVoord 已提交
183
        UNITY_OUTPUT_CHAR('-');
184
        number = (UNITY_UINT)(-number_to_print);
M
Mark VanderVoord 已提交
185
    }
186
    UnityPrintNumberUnsigned(number);
M
Mark VanderVoord 已提交
187 188
}

189 190
/*-----------------------------------------------
 * basically do an itoa using as little ram as possible */
191
void UnityPrintNumberUnsigned(const UNITY_UINT number)
M
Mark VanderVoord 已提交
192
{
193
    UNITY_UINT divisor = 1;
M
Mark VanderVoord 已提交
194

195
    /* figure out initial divisor */
M
Mark VanderVoord 已提交
196 197
    while (number / divisor > 9)
    {
198
        divisor *= 10;
M
Mark VanderVoord 已提交
199 200
    }

201
    /* now mod and print, then divide divisor */
M
Mark VanderVoord 已提交
202 203 204 205
    do
    {
        UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
        divisor /= 10;
206
    } while (divisor > 0);
M
Mark VanderVoord 已提交
207 208
}

209
/*-----------------------------------------------*/
210
void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print)
M
Mark VanderVoord 已提交
211
{
212
    int nibble;
M
Mark VanderVoord 已提交
213
    char nibbles = nibbles_to_print;
214 215
    if ((unsigned)nibbles > (2 * sizeof(number)))
        nibbles = 2 * sizeof(number);
M
Mark VanderVoord 已提交
216 217 218

    while (nibbles > 0)
    {
219
        nibbles--;
220
        nibble = (int)(number >> (nibbles * 4)) & 0x0F;
M
Mark VanderVoord 已提交
221 222 223 224 225 226 227 228 229 230 231
        if (nibble <= 9)
        {
            UNITY_OUTPUT_CHAR((char)('0' + nibble));
        }
        else
        {
            UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble));
        }
    }
}

232
/*-----------------------------------------------*/
233
void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number)
M
Mark VanderVoord 已提交
234
{
235 236
    UNITY_UINT current_bit = (UNITY_UINT)1 << (UNITY_INT_WIDTH - 1);
    UNITY_INT32 i;
M
Mark VanderVoord 已提交
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258

    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;
    }
}

259
/*-----------------------------------------------*/
J
jsalling 已提交
260
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
261 262 263 264 265
/* This function prints a floating-point value in a format similar to
 * printf("%.6g").  It can work with either single- or double-precision,
 * but for simplicity, it prints only 6 significant digits in either case.
 * Printing more than 6 digits accurately is hard (at least in the single-
 * precision case) and isn't attempted here. */
266
void UnityPrintFloat(const UNITY_DOUBLE input_number)
M
Mark VanderVoord 已提交
267
{
268
    UNITY_DOUBLE number = input_number;
269

270 271
    /* print minus sign (including for negative zero) */
    if (number < 0.0f || (number == 0.0f && 1.0f / number < 0.0f))
J
jsalling 已提交
272 273
    {
        UNITY_OUTPUT_CHAR('-');
274
        number = -number;
J
jsalling 已提交
275
    }
276

277 278 279 280 281
    /* handle zero, NaN, and +/- infinity */
    if (number == 0.0f) UnityPrint("0");
    else if (isnan(number)) UnityPrint("nan");
    else if (isinf(number)) UnityPrint("inf");
    else
J
jsalling 已提交
282
    {
283
        int exponent = 0;
J
John Lindgren 已提交
284 285 286
        int decimals, digits;
        UNITY_INT32 n;
        char buf[16];
287

288 289 290 291 292 293 294
        /* scale up or down by powers of 10 */
        while (number < 100000.0f / 1e6f)  { number *= 1e6f; exponent -= 6; }
        while (number < 100000.0f)         { number *= 10.0f; exponent--; }
        while (number > 1000000.0f * 1e6f) { number /= 1e6f; exponent += 6; }
        while (number > 1000000.0f)        { number /= 10.0f; exponent++; }

        /* round to nearest integer */
J
John Lindgren 已提交
295
        n = ((UNITY_INT32)(number + number) + 1) / 2;
296
        if (n > 999999)
297
        {
298 299
            n = 100000;
            exponent++;
300 301
        }

302
        /* determine where to place decimal point */
J
John Lindgren 已提交
303
        decimals = (exponent <= 0 && exponent >= -9) ? -exponent : 5;
304 305 306 307
        exponent += decimals;

        /* truncate trailing zeroes after decimal point */
        while (decimals > 0 && n % 10 == 0)
308
        {
309 310 311 312 313
            n /= 10;
            decimals--;
        }

        /* build up buffer in reverse order */
J
John Lindgren 已提交
314
        digits = 0;
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
        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]);
            }
351
        }
J
jsalling 已提交
352
    }
M
Mark VanderVoord 已提交
353
}
J
jsalling 已提交
354
#endif /* ! UNITY_EXCLUDE_FLOAT_PRINT */
M
Mark VanderVoord 已提交
355

356
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
357 358 359 360
static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line)
{
    UnityPrint(file);
    UNITY_OUTPUT_CHAR(':');
361
    UnityPrintNumber((UNITY_INT)line);
M
Mark VanderVoord 已提交
362 363 364 365 366
    UNITY_OUTPUT_CHAR(':');
    UnityPrint(Unity.CurrentTestName);
    UNITY_OUTPUT_CHAR(':');
}

367
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
368 369 370 371 372 373 374
static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line)
{
    UnityTestResultsBegin(Unity.TestFile, line);
    UnityPrint(UnityStrFail);
    UNITY_OUTPUT_CHAR(':');
}

375
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
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;
394
    UNITY_EXEC_TIME_RESET();
M
Mark VanderVoord 已提交
395
    UNITY_PRINT_EOL();
396
    UNITY_FLUSH_CALL();
M
Mark VanderVoord 已提交
397 398
}

399
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
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);
    }
}

422
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
423 424 425 426 427 428 429 430 431 432 433
static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual)
{
    UnityPrint(UnityStrExpected);
    if (expected != NULL)
    {
        UNITY_OUTPUT_CHAR('\'');
        UnityPrint(expected);
        UNITY_OUTPUT_CHAR('\'');
    }
    else
    {
434
        UnityPrint(UnityStrNull);
M
Mark VanderVoord 已提交
435 436 437 438 439 440 441 442 443 444
    }
    UnityPrint(UnityStrWas);
    if (actual != NULL)
    {
        UNITY_OUTPUT_CHAR('\'');
        UnityPrint(actual);
        UNITY_OUTPUT_CHAR('\'');
    }
    else
    {
445
        UnityPrint(UnityStrNull);
M
Mark VanderVoord 已提交
446 447 448
    }
}

449
/*-----------------------------------------------*/
450 451 452
static void UnityPrintExpectedAndActualStringsLen(const char* expected,
                                                  const char* actual,
                                                  const UNITY_UINT32 length)
M
Mark VanderVoord 已提交
453 454 455 456 457 458 459 460 461 462
{
    UnityPrint(UnityStrExpected);
    if (expected != NULL)
    {
        UNITY_OUTPUT_CHAR('\'');
        UnityPrintLen(expected, length);
        UNITY_OUTPUT_CHAR('\'');
    }
    else
    {
463
        UnityPrint(UnityStrNull);
M
Mark VanderVoord 已提交
464 465 466 467 468 469 470 471 472 473
    }
    UnityPrint(UnityStrWas);
    if (actual != NULL)
    {
        UNITY_OUTPUT_CHAR('\'');
        UnityPrintLen(actual, length);
        UNITY_OUTPUT_CHAR('\'');
    }
    else
    {
474
        UnityPrint(UnityStrNull);
M
Mark VanderVoord 已提交
475 476 477
    }
}

478 479 480
/*-----------------------------------------------
 * Assertion & Control Helpers
 *-----------------------------------------------*/
M
Mark VanderVoord 已提交
481

482 483 484 485
static int UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected,
                               UNITY_INTERNAL_PTR actual,
                               const UNITY_LINE_TYPE lineNumber,
                               const char* msg)
M
Mark VanderVoord 已提交
486
{
487
    if (expected == actual) return 0; /* Both are NULL or same pointer */
M
Mark VanderVoord 已提交
488

489
    /* print and return true if just expected is NULL */
M
Mark VanderVoord 已提交
490 491 492 493 494
    if (expected == NULL)
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrNullPointerForExpected);
        UnityAddMsgIfSpecified(msg);
495
        return 1;
M
Mark VanderVoord 已提交
496 497
    }

498
    /* print and return true if just actual is NULL */
M
Mark VanderVoord 已提交
499 500 501 502 503
    if (actual == NULL)
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrNullPointerForActual);
        UnityAddMsgIfSpecified(msg);
504
        return 1;
M
Mark VanderVoord 已提交
505 506
    }

507
    return 0; /* return false if neither is NULL */
M
Mark VanderVoord 已提交
508 509
}

510 511 512
/*-----------------------------------------------
 * Assertion Functions
 *-----------------------------------------------*/
M
Mark VanderVoord 已提交
513

514 515 516
void UnityAssertBits(const UNITY_INT mask,
                     const UNITY_INT expected,
                     const UNITY_INT actual,
M
Mark VanderVoord 已提交
517 518 519
                     const char* msg,
                     const UNITY_LINE_TYPE lineNumber)
{
520
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
521 522 523 524 525

    if ((mask & expected) != (mask & actual))
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrExpected);
526
        UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)expected);
M
Mark VanderVoord 已提交
527
        UnityPrint(UnityStrWas);
528
        UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)actual);
M
Mark VanderVoord 已提交
529 530 531 532 533
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

534
/*-----------------------------------------------*/
535 536
void UnityAssertEqualNumber(const UNITY_INT expected,
                            const UNITY_INT actual,
M
Mark VanderVoord 已提交
537 538 539 540
                            const char* msg,
                            const UNITY_LINE_TYPE lineNumber,
                            const UNITY_DISPLAY_STYLE_T style)
{
541
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
542 543 544 545 546 547 548 549 550 551 552 553 554

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

555
/*-----------------------------------------------*/
556 557 558 559 560 561
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)
562
{
563
    int failed = 0;
564 565
    RETURN_IF_FAIL_OR_IGNORE;

566 567 568 569
    if (threshold == actual && compare & UNITY_EQUAL_TO) return;
    if (threshold == actual) failed = 1;

    if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
570
    {
571 572 573 574 575 576 577
        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;
578 579
    }

580
    if (failed)
581 582 583 584
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrExpected);
        UnityPrintNumberByStyle(actual, style);
585 586 587
        if (compare & UNITY_GREATER_THAN) UnityPrint(UnityStrGt);
        if (compare & UNITY_SMALLER_THAN) UnityPrint(UnityStrLt);
        if (compare & UNITY_EQUAL_TO)     UnityPrint(UnityStrOrEqual);
588 589 590 591 592 593
        UnityPrintNumberByStyle(threshold, style);
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

594 595 596 597 598 599 600
#define UnityPrintPointlessAndBail()       \
{                                          \
    UnityTestResultsFailBegin(lineNumber); \
    UnityPrint(UnityStrPointless);         \
    UnityAddMsgIfSpecified(msg);           \
    UNITY_FAIL_AND_BAIL; }

601
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
602 603
void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
                              UNITY_INTERNAL_PTR actual,
604
                              const UNITY_UINT32 num_elements,
M
Mark VanderVoord 已提交
605 606
                              const char* msg,
                              const UNITY_LINE_TYPE lineNumber,
607 608
                              const UNITY_DISPLAY_STYLE_T style,
                              const UNITY_FLAGS_T flags)
M
Mark VanderVoord 已提交
609
{
610
    UNITY_UINT32 elements = num_elements;
611
    unsigned int length   = style & 0xF;
M
Mark VanderVoord 已提交
612

613
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
614

615 616 617 618
    if (num_elements == 0)
    {
        UnityPrintPointlessAndBail();
    }
M
Mark VanderVoord 已提交
619

620 621 622
    if (expected == actual) return; /* Both are NULL or same pointer */
    if (UnityIsOneArrayNull(expected, actual, lineNumber, msg))
        UNITY_FAIL_AND_BAIL;
M
Mark VanderVoord 已提交
623

624
    while ((elements > 0) && elements--)
M
Mark VanderVoord 已提交
625
    {
626 627
        UNITY_INT expect_val;
        UNITY_INT actual_val;
628 629 630 631 632 633 634 635 636 637
        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 已提交
638
#ifdef UNITY_SUPPORT_64
639 640 641 642
            case 8:
                expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected;
                actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual;
                break;
M
Mark VanderVoord 已提交
643
#endif
644 645 646 647 648
            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;
649 650 651 652
        }

        if (expect_val != actual_val)
        {
653
            if (style & UNITY_DISPLAY_RANGE_UINT && length < sizeof(expect_val))
654 655 656 657 658 659
            {   /* 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;
            }
660 661 662 663 664 665 666 667 668 669
            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;
        }
670 671 672 673
        if (flags == UNITY_ARRAY_TO_ARRAY)
        {
            expected = (UNITY_INTERNAL_PTR)(length + (const char*)expected);
        }
674
        actual   = (UNITY_INTERNAL_PTR)(length + (const char*)actual);
M
Mark VanderVoord 已提交
675 676 677
    }
}

678
/*-----------------------------------------------*/
679
#ifndef UNITY_EXCLUDE_FLOAT
680
/* Wrap this define in a function with variable types as float or double */
681 682 683 684 685 686 687
#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)))
688
    /* This first part of this condition will catch any NaN or Infinite values */
689 690 691 692 693
#ifndef UNITY_NAN_NOT_EQUAL_NAN
  #define UNITY_NAN_CHECK isnan(expected) && isnan(actual)
#else
  #define UNITY_NAN_CHECK 0
#endif
694

695 696
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
  #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \
697
  {                                                               \
698 699 700
    UnityPrint(UnityStrExpected);                                 \
    UnityPrintFloat(expected);                                    \
    UnityPrint(UnityStrWas);                                      \
701
    UnityPrintFloat(actual); }
702 703 704 705 706
#else
  #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \
    UnityPrint(UnityStrDelta)
#endif /* UNITY_EXCLUDE_FLOAT_PRINT */

707
static int UnityFloatsWithin(UNITY_FLOAT delta, UNITY_FLOAT expected, UNITY_FLOAT actual)
708
{
709
    UNITY_FLOAT diff;
710 711 712
    UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff);
}

713 714 715
void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected,
                                UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual,
                                const UNITY_UINT32 num_elements,
M
Mark VanderVoord 已提交
716
                                const char* msg,
717 718
                                const UNITY_LINE_TYPE lineNumber,
                                const UNITY_FLAGS_T flags)
M
Mark VanderVoord 已提交
719
{
720
    UNITY_UINT32 elements = num_elements;
721 722
    UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_expected = expected;
    UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_actual = actual;
M
Mark VanderVoord 已提交
723

724
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
725

726 727 728 729
    if (elements == 0)
    {
        UnityPrintPointlessAndBail();
    }
M
Mark VanderVoord 已提交
730

731 732 733
    if (expected == actual) return; /* Both are NULL or same pointer */
    if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
        UNITY_FAIL_AND_BAIL;
M
Mark VanderVoord 已提交
734 735 736

    while (elements--)
    {
737
        if (!UnityFloatsWithin(*ptr_expected * UNITY_FLOAT_PRECISION, *ptr_expected, *ptr_actual))
M
Mark VanderVoord 已提交
738 739 740
        {
            UnityTestResultsFailBegin(lineNumber);
            UnityPrint(UnityStrElement);
741
            UnityPrintNumberUnsigned(num_elements - elements - 1);
742
            UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)*ptr_expected, (UNITY_DOUBLE)*ptr_actual);
M
Mark VanderVoord 已提交
743 744 745
            UnityAddMsgIfSpecified(msg);
            UNITY_FAIL_AND_BAIL;
        }
746 747 748 749
        if (flags == UNITY_ARRAY_TO_ARRAY)
        {
            ptr_expected++;
        }
750
        ptr_actual++;
M
Mark VanderVoord 已提交
751 752 753
    }
}

754
/*-----------------------------------------------*/
755 756 757
void UnityAssertFloatsWithin(const UNITY_FLOAT delta,
                             const UNITY_FLOAT expected,
                             const UNITY_FLOAT actual,
M
Mark VanderVoord 已提交
758 759 760
                             const char* msg,
                             const UNITY_LINE_TYPE lineNumber)
{
761
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
762 763


764
    if (!UnityFloatsWithin(delta, expected, actual))
M
Mark VanderVoord 已提交
765 766
    {
        UnityTestResultsFailBegin(lineNumber);
767
        UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual);
M
Mark VanderVoord 已提交
768 769 770 771 772
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

773
/*-----------------------------------------------*/
774
void UnityAssertFloatSpecial(const UNITY_FLOAT actual,
M
Mark VanderVoord 已提交
775 776 777 778
                             const char* msg,
                             const UNITY_LINE_TYPE lineNumber,
                             const UNITY_FLOAT_TRAIT_T style)
{
779 780 781 782
    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 已提交
783

784
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
785

786
    switch (style)
M
Mark VanderVoord 已提交
787 788 789
    {
        case UNITY_FLOAT_IS_INF:
        case UNITY_FLOAT_IS_NOT_INF:
790
            is_trait = isinf(actual) && (actual > 0);
M
Mark VanderVoord 已提交
791 792 793
            break;
        case UNITY_FLOAT_IS_NEG_INF:
        case UNITY_FLOAT_IS_NOT_NEG_INF:
794
            is_trait = isinf(actual) && (actual < 0);
M
Mark VanderVoord 已提交
795 796 797 798
            break;

        case UNITY_FLOAT_IS_NAN:
        case UNITY_FLOAT_IS_NOT_NAN:
799
            is_trait = isnan(actual) ? 1 : 0;
M
Mark VanderVoord 已提交
800 801
            break;

802
        case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */
M
Mark VanderVoord 已提交
803
        case UNITY_FLOAT_IS_NOT_DET:
804
            is_trait = !isinf(actual) && !isnan(actual);
M
Mark VanderVoord 已提交
805 806 807
            break;

        default:
808 809 810
            trait_index = 0;
            trait_names[0] = UnityStrInvalidFloatTrait;
            break;
M
Mark VanderVoord 已提交
811 812 813 814 815 816 817 818 819 820
    }

    if (is_trait != should_be_trait)
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrExpected);
        if (!should_be_trait)
            UnityPrint(UnityStrNot);
        UnityPrint(trait_names[trait_index]);
        UnityPrint(UnityStrWas);
J
jsalling 已提交
821
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
822
        UnityPrintFloat((UNITY_DOUBLE)actual);
M
Mark VanderVoord 已提交
823 824 825 826 827 828 829 830 831 832
#else
        if (should_be_trait)
            UnityPrint(UnityStrNot);
        UnityPrint(trait_names[trait_index]);
#endif
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

833
#endif /* not UNITY_EXCLUDE_FLOAT */
M
Mark VanderVoord 已提交
834

835
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
836
#ifndef UNITY_EXCLUDE_DOUBLE
837
static int UnityDoublesWithin(UNITY_DOUBLE delta, UNITY_DOUBLE expected, UNITY_DOUBLE actual)
838
{
839
    UNITY_DOUBLE diff;
840 841 842
    UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff);
}

843 844 845
void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected,
                                 UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual,
                                 const UNITY_UINT32 num_elements,
M
Mark VanderVoord 已提交
846
                                 const char* msg,
847 848
                                 const UNITY_LINE_TYPE lineNumber,
                                 const UNITY_FLAGS_T flags)
M
Mark VanderVoord 已提交
849
{
850
    UNITY_UINT32 elements = num_elements;
851 852
    UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_expected = expected;
    UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_actual = actual;
M
Mark VanderVoord 已提交
853

854
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
855

856 857 858 859
    if (elements == 0)
    {
        UnityPrintPointlessAndBail();
    }
M
Mark VanderVoord 已提交
860

861 862 863
    if (expected == actual) return; /* Both are NULL or same pointer */
    if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
        UNITY_FAIL_AND_BAIL;
M
Mark VanderVoord 已提交
864 865 866

    while (elements--)
    {
867
        if (!UnityDoublesWithin(*ptr_expected * UNITY_DOUBLE_PRECISION, *ptr_expected, *ptr_actual))
M
Mark VanderVoord 已提交
868 869 870
        {
            UnityTestResultsFailBegin(lineNumber);
            UnityPrint(UnityStrElement);
871
            UnityPrintNumberUnsigned(num_elements - elements - 1);
872
            UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(*ptr_expected, *ptr_actual);
M
Mark VanderVoord 已提交
873 874 875
            UnityAddMsgIfSpecified(msg);
            UNITY_FAIL_AND_BAIL;
        }
876 877 878 879
        if (flags == UNITY_ARRAY_TO_ARRAY)
        {
            ptr_expected++;
        }
880
        ptr_actual++;
M
Mark VanderVoord 已提交
881 882 883
    }
}

884
/*-----------------------------------------------*/
885 886 887
void UnityAssertDoublesWithin(const UNITY_DOUBLE delta,
                              const UNITY_DOUBLE expected,
                              const UNITY_DOUBLE actual,
M
Mark VanderVoord 已提交
888 889 890
                              const char* msg,
                              const UNITY_LINE_TYPE lineNumber)
{
891
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
892

893
    if (!UnityDoublesWithin(delta, expected, actual))
M
Mark VanderVoord 已提交
894 895
    {
        UnityTestResultsFailBegin(lineNumber);
896
        UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual);
M
Mark VanderVoord 已提交
897 898 899 900 901
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

902
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
903

904
void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual,
M
Mark VanderVoord 已提交
905 906 907 908
                              const char* msg,
                              const UNITY_LINE_TYPE lineNumber,
                              const UNITY_FLOAT_TRAIT_T style)
{
909 910 911 912
    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 已提交
913

914
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
915

916
    switch (style)
M
Mark VanderVoord 已提交
917 918 919
    {
        case UNITY_FLOAT_IS_INF:
        case UNITY_FLOAT_IS_NOT_INF:
920
            is_trait = isinf(actual) && (actual > 0);
M
Mark VanderVoord 已提交
921 922 923
            break;
        case UNITY_FLOAT_IS_NEG_INF:
        case UNITY_FLOAT_IS_NOT_NEG_INF:
924
            is_trait = isinf(actual) && (actual < 0);
M
Mark VanderVoord 已提交
925 926 927 928
            break;

        case UNITY_FLOAT_IS_NAN:
        case UNITY_FLOAT_IS_NOT_NAN:
929
            is_trait = isnan(actual) ? 1 : 0;
M
Mark VanderVoord 已提交
930 931
            break;

932
        case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */
M
Mark VanderVoord 已提交
933
        case UNITY_FLOAT_IS_NOT_DET:
934
            is_trait = !isinf(actual) && !isnan(actual);
M
Mark VanderVoord 已提交
935 936 937
            break;

        default:
938 939 940
            trait_index = 0;
            trait_names[0] = UnityStrInvalidFloatTrait;
            break;
M
Mark VanderVoord 已提交
941 942 943 944 945 946 947 948 949 950
    }

    if (is_trait != should_be_trait)
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrExpected);
        if (!should_be_trait)
            UnityPrint(UnityStrNot);
        UnityPrint(trait_names[trait_index]);
        UnityPrint(UnityStrWas);
J
jsalling 已提交
951
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
M
Mark VanderVoord 已提交
952 953 954 955 956 957 958 959 960 961 962
        UnityPrintFloat(actual);
#else
        if (should_be_trait)
            UnityPrint(UnityStrNot);
        UnityPrint(trait_names[trait_index]);
#endif
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

963
#endif /* not UNITY_EXCLUDE_DOUBLE */
M
Mark VanderVoord 已提交
964

965
/*-----------------------------------------------*/
966 967 968 969 970 971
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 已提交
972
{
973
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
974 975 976 977

    if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
    {
        if (actual > expected)
978
            Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(actual - expected) > delta);
M
Mark VanderVoord 已提交
979
        else
M
Max Bruckner 已提交
980
            Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(expected - actual) > delta);
M
Mark VanderVoord 已提交
981 982 983
    }
    else
    {
984
        if ((UNITY_UINT)actual > (UNITY_UINT)expected)
M
Max Bruckner 已提交
985
            Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(actual - expected) > delta);
M
Mark VanderVoord 已提交
986
        else
M
Max Bruckner 已提交
987
            Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(expected - actual) > delta);
M
Mark VanderVoord 已提交
988 989 990 991 992 993
    }

    if (Unity.CurrentTestFailed)
    {
        UnityTestResultsFailBegin(lineNumber);
        UnityPrint(UnityStrDelta);
994
        UnityPrintNumberByStyle((UNITY_INT)delta, style);
M
Mark VanderVoord 已提交
995 996 997 998 999 1000 1001 1002 1003
        UnityPrint(UnityStrExpected);
        UnityPrintNumberByStyle(expected, style);
        UnityPrint(UnityStrWas);
        UnityPrintNumberByStyle(actual, style);
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
    }
}

1004
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1005 1006 1007 1008 1009
void UnityAssertEqualString(const char* expected,
                            const char* actual,
                            const char* msg,
                            const UNITY_LINE_TYPE lineNumber)
{
1010
    UNITY_UINT32 i;
M
Mark VanderVoord 已提交
1011

1012
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1013

1014
    /* if both pointers not null compare the strings */
M
Mark VanderVoord 已提交
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
    if (expected && actual)
    {
        for (i = 0; expected[i] || actual[i]; i++)
        {
            if (expected[i] != actual[i])
            {
                Unity.CurrentTestFailed = 1;
                break;
            }
        }
    }
    else
1027
    { /* handle case of one pointers being null (if both null, test should pass) */
M
Mark VanderVoord 已提交
1028 1029 1030 1031 1032 1033 1034 1035
        if (expected != actual)
        {
            Unity.CurrentTestFailed = 1;
        }
    }

    if (Unity.CurrentTestFailed)
    {
1036 1037 1038 1039
        UnityTestResultsFailBegin(lineNumber);
        UnityPrintExpectedAndActualStrings(expected, actual);
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
M
Mark VanderVoord 已提交
1040 1041 1042
    }
}

1043
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1044
void UnityAssertEqualStringLen(const char* expected,
1045 1046 1047 1048
                               const char* actual,
                               const UNITY_UINT32 length,
                               const char* msg,
                               const UNITY_LINE_TYPE lineNumber)
M
Mark VanderVoord 已提交
1049
{
1050
    UNITY_UINT32 i;
M
Mark VanderVoord 已提交
1051

1052
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1053

1054
    /* if both pointers not null compare the strings */
M
Mark VanderVoord 已提交
1055 1056
    if (expected && actual)
    {
1057
        for (i = 0; (i < length) && (expected[i] || actual[i]); i++)
M
Mark VanderVoord 已提交
1058 1059 1060 1061 1062 1063 1064 1065 1066
        {
            if (expected[i] != actual[i])
            {
                Unity.CurrentTestFailed = 1;
                break;
            }
        }
    }
    else
1067
    { /* handle case of one pointers being null (if both null, test should pass) */
M
Mark VanderVoord 已提交
1068 1069 1070 1071 1072 1073 1074 1075
        if (expected != actual)
        {
            Unity.CurrentTestFailed = 1;
        }
    }

    if (Unity.CurrentTestFailed)
    {
1076 1077 1078 1079
        UnityTestResultsFailBegin(lineNumber);
        UnityPrintExpectedAndActualStringsLen(expected, actual, length);
        UnityAddMsgIfSpecified(msg);
        UNITY_FAIL_AND_BAIL;
M
Mark VanderVoord 已提交
1080 1081 1082
    }
}

1083
/*-----------------------------------------------*/
1084
void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
1085 1086 1087
                                 const char** actual,
                                 const UNITY_UINT32 num_elements,
                                 const char* msg,
1088 1089
                                 const UNITY_LINE_TYPE lineNumber,
                                 const UNITY_FLAGS_T flags)
M
Mark VanderVoord 已提交
1090
{
1091 1092
    UNITY_UINT32 i = 0;
    UNITY_UINT32 j = 0;
1093
    const char* expd = NULL;
1094
    const char* act = NULL;
M
Mark VanderVoord 已提交
1095

1096
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1097

1098
    /* if no elements, it's an error */
1099 1100 1101 1102
    if (num_elements == 0)
    {
        UnityPrintPointlessAndBail();
    }
M
Mark VanderVoord 已提交
1103

1104
    if ((const void*)expected == (const void*)actual)
1105 1106 1107 1108
    {
        return; /* Both are NULL or same pointer */
    }

1109
    if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
1110
    {
1111
        UNITY_FAIL_AND_BAIL;
1112 1113 1114 1115
    }

    if (flags != UNITY_ARRAY_TO_ARRAY)
    {
1116
        expd = (const char*)expected;
1117
    }
M
Mark VanderVoord 已提交
1118 1119 1120

    do
    {
1121 1122 1123
        act = actual[j];
        if (flags == UNITY_ARRAY_TO_ARRAY)
        {
1124
            expd = ((const char* const*)expected)[j];
1125 1126
        }

1127
        /* if both pointers not null compare the strings */
1128
        if (expd && act)
M
Mark VanderVoord 已提交
1129
        {
1130
            for (i = 0; expd[i] || act[i]; i++)
M
Mark VanderVoord 已提交
1131
            {
1132
                if (expd[i] != act[i])
M
Mark VanderVoord 已提交
1133 1134 1135 1136 1137 1138 1139
                {
                    Unity.CurrentTestFailed = 1;
                    break;
                }
            }
        }
        else
1140
        { /* handle case of one pointers being null (if both null, test should pass) */
1141
            if (expd != act)
M
Mark VanderVoord 已提交
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152
            {
                Unity.CurrentTestFailed = 1;
            }
        }

        if (Unity.CurrentTestFailed)
        {
            UnityTestResultsFailBegin(lineNumber);
            if (num_elements > 1)
            {
                UnityPrint(UnityStrElement);
1153
                UnityPrintNumberUnsigned(j);
M
Mark VanderVoord 已提交
1154
            }
1155
            UnityPrintExpectedAndActualStrings(expd, act);
M
Mark VanderVoord 已提交
1156 1157 1158 1159 1160 1161
            UnityAddMsgIfSpecified(msg);
            UNITY_FAIL_AND_BAIL;
        }
    } while (++j < num_elements);
}

1162
/*-----------------------------------------------*/
1163 1164 1165 1166 1167
void UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected,
                            UNITY_INTERNAL_PTR actual,
                            const UNITY_UINT32 length,
                            const UNITY_UINT32 num_elements,
                            const char* msg,
1168 1169
                            const UNITY_LINE_TYPE lineNumber,
                            const UNITY_FLAGS_T flags)
M
Mark VanderVoord 已提交
1170 1171 1172
{
    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;
1173 1174
    UNITY_UINT32 elements = num_elements;
    UNITY_UINT32 bytes;
M
Mark VanderVoord 已提交
1175

1176
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1177

1178 1179 1180 1181
    if ((elements == 0) || (length == 0))
    {
        UnityPrintPointlessAndBail();
    }
M
Mark VanderVoord 已提交
1182

1183 1184 1185
    if (expected == actual) return; /* Both are NULL or same pointer */
    if (UnityIsOneArrayNull(expected, actual, lineNumber, msg))
        UNITY_FAIL_AND_BAIL;
M
Mark VanderVoord 已提交
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198

    while (elements--)
    {
        bytes = length;
        while (bytes--)
        {
            if (*ptr_exp != *ptr_act)
            {
                UnityTestResultsFailBegin(lineNumber);
                UnityPrint(UnityStrMemory);
                if (num_elements > 1)
                {
                    UnityPrint(UnityStrElement);
1199
                    UnityPrintNumberUnsigned(num_elements - elements - 1);
M
Mark VanderVoord 已提交
1200 1201
                }
                UnityPrint(UnityStrByte);
1202
                UnityPrintNumberUnsigned(length - bytes - 1);
M
Mark VanderVoord 已提交
1203 1204 1205 1206 1207 1208 1209
                UnityPrint(UnityStrExpected);
                UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8);
                UnityPrint(UnityStrWas);
                UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8);
                UnityAddMsgIfSpecified(msg);
                UNITY_FAIL_AND_BAIL;
            }
1210 1211
            ptr_exp++;
            ptr_act++;
M
Mark VanderVoord 已提交
1212
        }
1213 1214 1215 1216
        if (flags == UNITY_ARRAY_TO_VAL)
        {
            ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected;
        }
M
Mark VanderVoord 已提交
1217 1218 1219
    }
}

1220 1221 1222 1223 1224 1225 1226 1227 1228 1229
/*-----------------------------------------------*/

static union
{
    UNITY_INT8 i8;
    UNITY_INT16 i16;
    UNITY_INT32 i32;
#ifdef UNITY_SUPPORT_64
    UNITY_INT64 i64;
#endif
1230 1231 1232 1233 1234 1235
#ifndef UNITY_EXCLUDE_FLOAT
    float f;
#endif
#ifndef UNITY_EXCLUDE_DOUBLE
    double d;
#endif
1236 1237 1238 1239 1240 1241 1242
} UnityQuickCompare;

UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size)
{
    switch(size)
    {
        case 1:
1243
          UnityQuickCompare.i8 = (UNITY_INT8)num;
1244 1245 1246
          return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i8);

        case 2:
1247
          UnityQuickCompare.i16 = (UNITY_INT16)num;
1248 1249 1250 1251
          return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i16);

#ifdef UNITY_SUPPORT_64
        case 8:
1252
          UnityQuickCompare.i64 = (UNITY_INT64)num;
1253 1254
          return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i64);
#endif
1255
        default: /* 4 bytes */
1256
          UnityQuickCompare.i32 = (UNITY_INT32)num;
1257 1258 1259 1260
          return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i32);
    }
}

1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276
#ifndef UNITY_EXCLUDE_FLOAT
UNITY_INTERNAL_PTR UnityFloatToPtr(const float num)
{
    UnityQuickCompare.f = num;
    return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.f);
}
#endif

#ifndef UNITY_EXCLUDE_DOUBLE
UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num)
{
    UnityQuickCompare.d = num;
    return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.d);
}
#endif

1277 1278 1279
/*-----------------------------------------------
 * Control Functions
 *-----------------------------------------------*/
M
Mark VanderVoord 已提交
1280 1281 1282

void UnityFail(const char* msg, const UNITY_LINE_TYPE line)
{
1283
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1284 1285

    UnityTestResultsBegin(Unity.TestFile, line);
1286
    UnityPrint(UnityStrFail);
M
Mark VanderVoord 已提交
1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313
    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;
}

1314
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1315 1316
void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line)
{
1317
    RETURN_IF_FAIL_OR_IGNORE;
M
Mark VanderVoord 已提交
1318 1319 1320 1321 1322

    UnityTestResultsBegin(Unity.TestFile, line);
    UnityPrint(UnityStrIgnore);
    if (msg != NULL)
    {
1323 1324 1325
        UNITY_OUTPUT_CHAR(':');
        UNITY_OUTPUT_CHAR(' ');
        UnityPrint(msg);
M
Mark VanderVoord 已提交
1326 1327 1328 1329
    }
    UNITY_IGNORE_AND_BAIL;
}

1330
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341
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();
    }
1342
    if (TEST_PROTECT())
M
Mark VanderVoord 已提交
1343 1344 1345 1346 1347 1348
    {
        tearDown();
    }
    UnityConcludeTest();
}

1349
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359
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;
1360
    UNITY_EXEC_TIME_RESET();
M
Mark VanderVoord 已提交
1361 1362 1363 1364 1365

    UNITY_CLR_DETAILS();
    UNITY_OUTPUT_START();
}

1366
/*-----------------------------------------------*/
M
Mark VanderVoord 已提交
1367 1368 1369 1370 1371
int UnityEnd(void)
{
    UNITY_PRINT_EOL();
    UnityPrint(UnityStrBreaker);
    UNITY_PRINT_EOL();
1372
    UnityPrintNumber((UNITY_INT)(Unity.NumberOfTests));
M
Mark VanderVoord 已提交
1373
    UnityPrint(UnityStrResultsTests);
1374
    UnityPrintNumber((UNITY_INT)(Unity.TestFailures));
M
Mark VanderVoord 已提交
1375
    UnityPrint(UnityStrResultsFailures);
1376
    UnityPrintNumber((UNITY_INT)(Unity.TestIgnores));
M
Mark VanderVoord 已提交
1377 1378 1379 1380
    UnityPrint(UnityStrResultsIgnored);
    UNITY_PRINT_EOL();
    if (Unity.TestFailures == 0U)
    {
1381
        UnityPrint(UnityStrOk);
M
Mark VanderVoord 已提交
1382 1383 1384
    }
    else
    {
1385
        UnityPrint(UnityStrFail);
1386 1387 1388
#ifdef UNITY_DIFFERENTIATE_FINAL_FAIL
        UNITY_OUTPUT_CHAR('E'); UNITY_OUTPUT_CHAR('D');
#endif
M
Mark VanderVoord 已提交
1389 1390
    }
    UNITY_PRINT_EOL();
1391
    UNITY_FLUSH_CALL();
M
Mark VanderVoord 已提交
1392 1393 1394 1395
    UNITY_OUTPUT_COMPLETE();
    return (int)(Unity.TestFailures);
}

1396 1397 1398
/*-----------------------------------------------
 * Command Line Argument Support
 *-----------------------------------------------*/
1399
#ifdef UNITY_USE_COMMAND_LINE_ARGS
1400 1401 1402

char* UnityOptionIncludeNamed = NULL;
char* UnityOptionExcludeNamed = NULL;
1403
int UnityVerbosity            = 1;
1404 1405 1406 1407 1408 1409 1410 1411 1412 1413

int UnityParseOptions(int argc, char** argv)
{
    UnityOptionIncludeNamed = NULL;
    UnityOptionExcludeNamed = NULL;

    for (int i = 1; i < argc; i++)
    {
        if (argv[i][0] == '-')
        {
1414
            switch (argv[i][1])
1415 1416
            {
                case 'l': /* list tests */
1417
                    return -1;
1418
                case 'n': /* include tests with name including this string */
1419 1420 1421 1422
                case 'f': /* an alias for -n */
                    if (argv[i][2] == '=')
                        UnityOptionIncludeNamed = &argv[i][3];
                    else if (++i < argc)
1423 1424 1425 1426 1427
                        UnityOptionIncludeNamed = argv[i];
                    else
                    {
                        UnityPrint("ERROR: No Test String to Include Matches For");
                        UNITY_PRINT_EOL();
1428
                        return 1;
1429 1430 1431 1432 1433 1434 1435 1436 1437
                    }
                    break;
                case 'q': /* quiet */
                    UnityVerbosity = 0;
                    break;
                case 'v': /* verbose */
                    UnityVerbosity = 2;
                    break;
                case 'x': /* exclude tests with name including this string */
1438 1439 1440
                    if (argv[i][2] == '=')
                        UnityOptionExcludeNamed = &argv[i][3];
                    else if (++i < argc)
1441 1442 1443 1444 1445
                        UnityOptionExcludeNamed = argv[i];
                    else
                    {
                        UnityPrint("ERROR: No Test String to Exclude Matches For");
                        UNITY_PRINT_EOL();
1446
                        return 1;
1447 1448 1449 1450
                    }
                    break;
                default:
                    UnityPrint("ERROR: Unknown Option ");
1451
                    UNITY_OUTPUT_CHAR(argv[i][1]);
1452 1453 1454 1455 1456 1457 1458 1459 1460
                    UNITY_PRINT_EOL();
                    return 1;
            }
        }
    }

    return 0;
}

1461
int IsStringInBiggerString(const char* longstring, const char* shortstring)
1462
{
1463 1464 1465
    const char* lptr = longstring;
    const char* sptr = shortstring;
    const char* lnext = lptr;
1466

1467 1468 1469
    if (*sptr == '*')
        return 1;

1470 1471 1472
    while (*lptr)
    {
        lnext = lptr + 1;
1473

1474 1475 1476 1477 1478
        /* If they current bytes match, go on to the next bytes */
        while (*lptr && *sptr && (*lptr == *sptr))
        {
            lptr++;
            sptr++;
1479

1480 1481 1482
            /* We're done if we match the entire string or up to a wildcard */
            if (*sptr == '*')
                return 1;
1483 1484 1485 1486 1487 1488 1489 1490
            if (*sptr == ',')
                return 1;
            if (*sptr == '"')
                return 1;
            if (*sptr == '\'')
                return 1;
            if (*sptr == ':')
                return 2;
1491 1492 1493 1494 1495 1496
            if (*sptr == 0)
                return 1;
        }

        /* Otherwise we start in the long pointer 1 character further and try again */
        lptr = lnext;
1497
        sptr = shortstring;
1498 1499
    }
    return 0;
1500 1501 1502 1503
}

int UnityStringArgumentMatches(const char* str)
{
1504 1505 1506
    int retval;
    const char* ptr1;
    const char* ptr2;
1507
    const char* ptrf;
1508

1509
    /* Go through the options and get the substrings for matching one at a time */
1510 1511 1512 1513 1514 1515
    ptr1 = str;
    while (ptr1[0] != 0)
    {
        if ((ptr1[0] == '"') || (ptr1[0] == '\''))
            ptr1++;

1516
        /* look for the start of the next partial */
1517
        ptr2 = ptr1;
1518
        ptrf = 0;
1519 1520
        do
        {
1521
            ptr2++;
1522 1523 1524 1525
            if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ','))
                ptrf = &ptr2[1];
        } while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ','));
        while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ',')))
1526 1527
            ptr2++;

1528
        /* done if complete filename match */
1529 1530 1531 1532
        retval = IsStringInBiggerString(Unity.TestFile, ptr1);
        if (retval == 1)
            return retval;

1533
        /* done if testname match after filename partial match */
1534
        if ((retval == 2) && (ptrf != 0))
1535
        {
1536
            if (IsStringInBiggerString(Unity.CurrentTestName, ptrf))
1537 1538 1539
                return 1;
        }

1540
        /* done if complete testname match */
1541 1542 1543 1544 1545 1546
        if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1)
            return 1;

        ptr1 = ptr2;
    }

1547
    /* we couldn't find a match for any substrings */
1548
    return 0;
1549
}
1550

1551 1552 1553 1554 1555 1556 1557 1558 1559 1560
int UnityTestMatches(void)
{
    /* Check if this test name matches the included test pattern */
    int retval;
    if (UnityOptionIncludeNamed)
    {
        retval = UnityStringArgumentMatches(UnityOptionIncludeNamed);
    }
    else
        retval = 1;
1561

1562 1563 1564 1565 1566
    /* Check if this test name matches the excluded test pattern */
    if (UnityOptionExcludeNamed)
    {
        if (UnityStringArgumentMatches(UnityOptionExcludeNamed))
            retval = 0;
1567
    }
1568
    return retval;
1569 1570
}

1571
#endif /* UNITY_USE_COMMAND_LINE_ARGS */
1572
/*-----------------------------------------------*/