1290001Sglebius/* =========================================================================
2290001Sglebius    Unity Project - A Test Framework for C
3290001Sglebius    Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams
4290001Sglebius    [Released under MIT License. Please refer to license.txt for details]
5290001Sglebius============================================================================ */
6290001Sglebius
7290001Sglebius#include "unity.h"
8290001Sglebius
9290001Sglebius#define UNITY_FAIL_AND_BAIL   { Unity.CurrentTestFailed  = 1; longjmp(Unity.AbortFrame, 1); }
10290001Sglebius#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; longjmp(Unity.AbortFrame, 1); }
11290001Sglebius/// return prematurely if we are already in failure or ignore state
12290001Sglebius#define UNITY_SKIP_EXECUTION  { if ((Unity.CurrentTestFailed != 0) || (Unity.CurrentTestIgnored != 0)) {return;} }
13290001Sglebius#define UNITY_PRINT_EOL       { UNITY_OUTPUT_CHAR('\n'); }
14290001Sglebius
15290001Sglebiusstruct _Unity Unity;
16290001Sglebius
17290001Sglebiusconst char UnityStrOk[]                     = "OK";
18290001Sglebiusconst char UnityStrPass[]                   = "PASS";
19290001Sglebiusconst char UnityStrFail[]                   = "FAIL";
20290001Sglebiusconst char UnityStrIgnore[]                 = "IGNORE";
21290001Sglebiusconst char UnityStrXPASS[]                  = "XPASS";
22290001Sglebiusconst char UnityStrXFAIL[]                  = "XFAIL";
23290001Sglebiusconst char UnityStrNull[]                   = "NULL";
24290001Sglebiusconst char UnityStrSpacer[]                 = ". ";
25290001Sglebiusconst char UnityStrExpected[]               = " Expected ";
26290001Sglebiusconst char UnityStrWas[]                    = " Was ";
27290001Sglebiusconst char UnityStrTo[]                     = " To ";
28290001Sglebiusconst char UnityStrElement[]                = " Element ";
29290001Sglebiusconst char UnityStrByte[]                   = " Byte ";
30290001Sglebiusconst char UnityStrMemory[]                 = " Memory Mismatch.";
31290001Sglebiusconst char UnityStrDelta[]                  = " Values Not Within Delta ";
32290001Sglebiusconst char UnityStrPointless[]              = " You Asked Me To Compare Nothing, Which Was Pointless.";
33290001Sglebiusconst char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL";
34290001Sglebiusconst char UnityStrNullPointerForActual[]   = " Actual pointer was NULL";
35290001Sglebiusconst char UnityStrNot[]                    = "Not ";
36290001Sglebiusconst char UnityStrInf[]                    = "Infinity";
37290001Sglebiusconst char UnityStrNegInf[]                 = "Negative Infinity";
38290001Sglebiusconst char UnityStrNaN[]                    = "NaN";
39290001Sglebiusconst char UnityStrDet[]                    = "Determinate";
40290001Sglebiusconst char UnityStrErrFloat[]               = "Unity Floating Point Disabled";
41290001Sglebiusconst char UnityStrErrDouble[]              = "Unity Double Precision Disabled";
42290001Sglebiusconst char UnityStrErr64[]                  = "Unity 64-bit Support Disabled";
43290001Sglebiusconst char UnityStrBreaker[]                = "-----------------------";
44290001Sglebiusconst char UnityStrResultsTests[]           = " Tests: ";
45290001Sglebiusconst char UnityStrResultsFailures[]        = " Failures ";
46290001Sglebiusconst char UnityStrResultsIgnored[]         = " Ignored ";
47290001Sglebiusconst char UnityStrResultsXFAIL[]           = " XFAIL ";
48290001Sglebiusconst char UnityStrResultsXPASS[]           = " XPASS ";
49290001Sglebiusconst char UnityStrResultsPass[]            = " PASS ";
50290001Sglebius
51290001Sglebius
52290001Sglebius#ifndef UNITY_EXCLUDE_FLOAT
53290001Sglebius// Dividing by these constants produces +/- infinity.
54290001Sglebius// The rationale is given in UnityAssertFloatIsInf's body.
55290001Sglebiusstatic const _UF f_zero = 0.0f;
56290001Sglebius#ifndef UNITY_EXCLUDE_DOUBLE
57290001Sglebiusstatic const _UD d_zero = 0.0;
58290001Sglebius#endif
59290001Sglebius#endif
60290001Sglebius
61290001Sglebius// compiler-generic print formatting masks
62290001Sglebiusconst _U_UINT UnitySizeMask[] =
63290001Sglebius{
64290001Sglebius    255u,         // 0xFF
65290001Sglebius    65535u,       // 0xFFFF
66290001Sglebius    65535u,
67290001Sglebius    4294967295u,  // 0xFFFFFFFF
68290001Sglebius    4294967295u,
69290001Sglebius    4294967295u,
70290001Sglebius    4294967295u
71290001Sglebius#ifdef UNITY_SUPPORT_64
72290001Sglebius    ,0xFFFFFFFFFFFFFFFF
73290001Sglebius#endif
74290001Sglebius};
75290001Sglebius
76290001Sglebiusvoid UnityPrintFail(void);
77290001Sglebiusvoid UnityPrintOk(void);
78290001Sglebius
79290001Sglebius//-----------------------------------------------
80290001Sglebius// Pretty Printers & Test Result Output Handlers
81290001Sglebius//-----------------------------------------------
82290001Sglebius
83290001Sglebiusvoid UnityPrint(const char* string)
84290001Sglebius{
85290001Sglebius    const char* pch = string;
86290001Sglebius
87290001Sglebius    if (pch != NULL)
88290001Sglebius    {
89290001Sglebius        while (*pch)
90290001Sglebius        {
91290001Sglebius            // printable characters plus CR & LF are printed
92290001Sglebius            if ((*pch <= 126) && (*pch >= 32))
93290001Sglebius            {
94290001Sglebius                UNITY_OUTPUT_CHAR(*pch);
95290001Sglebius            }
96290001Sglebius            //write escaped carriage returns
97290001Sglebius            else if (*pch == 13)
98290001Sglebius            {
99290001Sglebius                UNITY_OUTPUT_CHAR('\\');
100290001Sglebius                UNITY_OUTPUT_CHAR('r');
101290001Sglebius            }
102290001Sglebius            //write escaped line feeds
103290001Sglebius            else if (*pch == 10)
104290001Sglebius            {
105290001Sglebius                UNITY_OUTPUT_CHAR('\\');
106290001Sglebius                UNITY_OUTPUT_CHAR('n');
107290001Sglebius            }
108290001Sglebius            // unprintable characters are shown as codes
109290001Sglebius            else
110290001Sglebius            {
111290001Sglebius                UNITY_OUTPUT_CHAR('\\');
112290001Sglebius                UnityPrintNumberHex((_U_UINT)*pch, 2);
113290001Sglebius            }
114290001Sglebius            pch++;
115290001Sglebius        }
116290001Sglebius    }
117290001Sglebius}
118290001Sglebius
119290001Sglebius//-----------------------------------------------
120290001Sglebiusvoid UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style)
121290001Sglebius{
122290001Sglebius    if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
123290001Sglebius    {
124290001Sglebius        UnityPrintNumber(number);
125290001Sglebius    }
126290001Sglebius    else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT)
127290001Sglebius    {
128290001Sglebius        UnityPrintNumberUnsigned(  (_U_UINT)number  &  UnitySizeMask[((_U_UINT)style & (_U_UINT)0x0F) - 1]  );
129290001Sglebius    }
130290001Sglebius    else
131290001Sglebius    {
132290001Sglebius        UnityPrintNumberHex((_U_UINT)number, (char)((style & 0x000F) << 1));
133290001Sglebius    }
134290001Sglebius}
135290001Sglebius
136290001Sglebius//-----------------------------------------------
137290001Sglebius/// basically do an itoa using as little ram as possible
138290001Sglebiusvoid UnityPrintNumber(const _U_SINT number_to_print)
139290001Sglebius{
140290001Sglebius    _U_SINT divisor = 1;
141290001Sglebius    _U_SINT next_divisor;
142290001Sglebius    _U_UINT number;
143290001Sglebius
144290001Sglebius    if (number_to_print == (1l << (UNITY_LONG_WIDTH-1)))
145290001Sglebius    {
146290001Sglebius        //The largest representable negative number
147290001Sglebius        UNITY_OUTPUT_CHAR('-');
148290001Sglebius        number = (1ul << (UNITY_LONG_WIDTH-1));
149290001Sglebius    }
150290001Sglebius    else if (number_to_print < 0)
151290001Sglebius    {
152290001Sglebius        //Some other negative number
153290001Sglebius        UNITY_OUTPUT_CHAR('-');
154290001Sglebius        number = (_U_UINT)(-number_to_print);
155290001Sglebius    }
156290001Sglebius    else
157290001Sglebius    {
158290001Sglebius        //Positive number
159290001Sglebius        number = (_U_UINT)number_to_print;
160290001Sglebius    }
161290001Sglebius
162290001Sglebius    // figure out initial divisor
163290001Sglebius    while (number / divisor > 9)
164290001Sglebius    {
165290001Sglebius        next_divisor = divisor * 10;
166290001Sglebius        if (next_divisor > divisor)
167290001Sglebius            divisor = next_divisor;
168290001Sglebius        else
169290001Sglebius            break;
170290001Sglebius    }
171290001Sglebius
172290001Sglebius    // now mod and print, then divide divisor
173290001Sglebius    do
174290001Sglebius    {
175290001Sglebius        UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
176290001Sglebius        divisor /= 10;
177290001Sglebius    }
178290001Sglebius    while (divisor > 0);
179290001Sglebius}
180290001Sglebius
181290001Sglebius//-----------------------------------------------
182290001Sglebius/// basically do an itoa using as little ram as possible
183290001Sglebiusvoid UnityPrintNumberUnsigned(const _U_UINT number)
184290001Sglebius{
185290001Sglebius    _U_UINT divisor = 1;
186290001Sglebius    _U_UINT next_divisor;
187290001Sglebius
188290001Sglebius    // figure out initial divisor
189290001Sglebius    while (number / divisor > 9)
190290001Sglebius    {
191290001Sglebius        next_divisor = divisor * 10;
192290001Sglebius        if (next_divisor > divisor)
193290001Sglebius            divisor = next_divisor;
194290001Sglebius        else
195290001Sglebius            break;
196290001Sglebius    }
197290001Sglebius
198290001Sglebius    // now mod and print, then divide divisor
199290001Sglebius    do
200290001Sglebius    {
201290001Sglebius        UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
202290001Sglebius        divisor /= 10;
203290001Sglebius    }
204290001Sglebius    while (divisor > 0);
205290001Sglebius}
206290001Sglebius
207290001Sglebius//-----------------------------------------------
208290001Sglebiusvoid UnityPrintNumberHex(const _U_UINT number, const char nibbles_to_print)
209290001Sglebius{
210290001Sglebius    _U_UINT nibble;
211290001Sglebius    char nibbles = nibbles_to_print;
212290001Sglebius    UNITY_OUTPUT_CHAR('0');
213290001Sglebius    UNITY_OUTPUT_CHAR('x');
214290001Sglebius
215290001Sglebius    while (nibbles > 0)
216290001Sglebius    {
217290001Sglebius        nibble = (number >> (--nibbles << 2)) & 0x0000000F;
218290001Sglebius        if (nibble <= 9)
219290001Sglebius        {
220290001Sglebius            UNITY_OUTPUT_CHAR((char)('0' + nibble));
221290001Sglebius        }
222290001Sglebius        else
223290001Sglebius        {
224290001Sglebius            UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble));
225290001Sglebius        }
226290001Sglebius    }
227290001Sglebius}
228290001Sglebius
229290001Sglebius//-----------------------------------------------
230290001Sglebiusvoid UnityPrintMask(const _U_UINT mask, const _U_UINT number)
231290001Sglebius{
232290001Sglebius    _U_UINT current_bit = (_U_UINT)1 << (UNITY_INT_WIDTH - 1);
233290001Sglebius    _US32 i;
234290001Sglebius
235290001Sglebius    for (i = 0; i < UNITY_INT_WIDTH; i++)
236290001Sglebius    {
237290001Sglebius        if (current_bit & mask)
238290001Sglebius        {
239290001Sglebius            if (current_bit & number)
240290001Sglebius            {
241290001Sglebius                UNITY_OUTPUT_CHAR('1');
242290001Sglebius            }
243290001Sglebius            else
244290001Sglebius            {
245290001Sglebius                UNITY_OUTPUT_CHAR('0');
246290001Sglebius            }
247290001Sglebius        }
248290001Sglebius        else
249290001Sglebius        {
250290001Sglebius            UNITY_OUTPUT_CHAR('X');
251290001Sglebius        }
252290001Sglebius        current_bit = current_bit >> 1;
253290001Sglebius    }
254290001Sglebius}
255290001Sglebius
256290001Sglebius//-----------------------------------------------
257290001Sglebius#ifdef UNITY_FLOAT_VERBOSE
258290001Sglebius#include <string.h>
259290001Sglebiusvoid UnityPrintFloat(_UF number)
260290001Sglebius{
261290001Sglebius    char TempBuffer[32];
262290001Sglebius    sprintf(TempBuffer, "%.6f", number);
263290001Sglebius    UnityPrint(TempBuffer);
264290001Sglebius}
265290001Sglebius#endif
266290001Sglebius
267290001Sglebius//-----------------------------------------------
268290001Sglebius
269290001Sglebiusvoid UnityPrintFail(void)
270290001Sglebius{
271290001Sglebius    UnityPrint(UnityStrFail);
272290001Sglebius}
273290001Sglebius
274290001Sglebiusvoid UnityPrintOk(void)
275290001Sglebius{
276290001Sglebius    UnityPrint(UnityStrOk);
277290001Sglebius}
278290001Sglebius
279290001Sglebius//-----------------------------------------------
280290001Sglebiusstatic void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line)
281290001Sglebius{
282290001Sglebius    UnityPrint(file);
283290001Sglebius    UNITY_OUTPUT_CHAR(':');
284290001Sglebius    UnityPrintNumber((_U_SINT)line);
285290001Sglebius    UNITY_OUTPUT_CHAR(':');
286290001Sglebius    UnityPrint(Unity.CurrentTestName);
287290001Sglebius    UNITY_OUTPUT_CHAR(':');
288290001Sglebius}
289290001Sglebius
290290001Sglebius//-----------------------------------------------
291290001Sglebiusstatic void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line)
292290001Sglebius{
293290001Sglebius    UnityTestResultsBegin(Unity.TestFile, line);
294290001Sglebius	if (Unity.isExpectingFail)
295290001Sglebius	{
296290001Sglebius		UnityPrint(UnityStrXFAIL);
297290001Sglebius	}
298290001Sglebius	else
299290001Sglebius	{
300290001Sglebius		UnityPrint(UnityStrFail);
301290001Sglebius	}
302290001Sglebius
303290001Sglebius    UNITY_OUTPUT_CHAR(':');
304290001Sglebius}
305290001Sglebius
306290001Sglebius//-----------------------------------------------
307290001Sglebiusvoid UnityConcludeTest(void)
308290001Sglebius{
309290001Sglebius#if 0
310290001Sglebius	if (Unity.isExpectingFail == 1 && Unity.CurrentTestFailed == 0)
311290001Sglebius	{
312290001Sglebius		printf("FAIL WAS EXPECTED, BUT IT DIDN'T HAPPEN?!");
313290001Sglebius		Unity.TestXPASSES++;
314290001Sglebius	}
315290001Sglebius
316290001Sglebius	else
317290001Sglebius#endif
318290001Sglebius	//cant be ignored and accepting fail at the same time!
319290001Sglebius	if (Unity.isExpectingFail == 1 && Unity.CurrentTestFailed == 1)
320290001Sglebius	{
321290001Sglebius		Unity.TestXFAILS++; //error message?!
322290001Sglebius		if (Unity.XFAILMessage != NULL)
323290001Sglebius		{
324290001Sglebius			if (Unity.XFAILMessage[0] != ' ')
325290001Sglebius			{
326290001Sglebius				printf(" ");
327290001Sglebius			}
328290001Sglebius
329290001Sglebius			printf("| ");
330290001Sglebius			printf("%s", Unity.XFAILMessage);
331290001Sglebius			Unity.XFAILMessage = NULL;
332290001Sglebius		}
333290001Sglebius		else
334290001Sglebius		{
335290001Sglebius			printf(" - EXPECTED FAIL!");
336290001Sglebius		}
337290001Sglebius	}
338290001Sglebius	else
339290001Sglebius
340290001Sglebius    if (Unity.CurrentTestIgnored)
341290001Sglebius    {
342290001Sglebius        Unity.TestIgnores++;
343290001Sglebius    }
344290001Sglebius    else if (!Unity.CurrentTestFailed)
345290001Sglebius    {
346290001Sglebius	if(Unity.isExpectingFail == 0) {
347290001Sglebius		UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber);
348290001Sglebius		UnityPrint(UnityStrPass);
349290001Sglebius		Unity.TestPasses++;
350290001Sglebius	}
351290001Sglebius
352290001Sglebius	//probably should remove the if... part
353290001Sglebius	else if (Unity.isExpectingFail == 1 && Unity.CurrentTestFailed == 0)
354290001Sglebius	{
355290001Sglebius
356290001Sglebius		UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber);
357290001Sglebius		UnityPrint(UnityStrXPASS);
358290001Sglebius		Unity.TestXPASSES++;
359290001Sglebius
360290001Sglebius		printf(" - FAIL WAS EXPECTED, BUT DIDN'T HAPPEN?!");
361290001Sglebius		//if (Unity.TestPasses > 0) { Unity.TestPasses--; }
362290001Sglebius	}
363290001Sglebius    }
364290001Sglebius    else
365290001Sglebius    {
366290001Sglebius        Unity.TestFailures++;
367290001Sglebius    }
368290001Sglebius
369290001Sglebius    Unity.CurrentTestFailed = 0;
370290001Sglebius    Unity.CurrentTestIgnored = 0;
371290001Sglebius    Unity.isExpectingFail = 0;
372290001Sglebius
373290001Sglebius    UNITY_PRINT_EOL;
374290001Sglebius}
375290001Sglebius
376290001Sglebius//-----------------------------------------------
377290001Sglebiusstatic void UnityAddMsgIfSpecified(const char* msg)
378290001Sglebius{
379290001Sglebius    if (msg)
380290001Sglebius    {
381290001Sglebius        UnityPrint(UnityStrSpacer);
382290001Sglebius        UnityPrint(msg);
383290001Sglebius    }
384290001Sglebius}
385290001Sglebius
386290001Sglebius//-----------------------------------------------
387290001Sglebiusstatic void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual)
388290001Sglebius{
389290001Sglebius    UnityPrint(UnityStrExpected);
390290001Sglebius    if (expected != NULL)
391290001Sglebius    {
392290001Sglebius        UNITY_OUTPUT_CHAR('\'');
393290001Sglebius        UnityPrint(expected);
394290001Sglebius        UNITY_OUTPUT_CHAR('\'');
395290001Sglebius    }
396290001Sglebius    else
397290001Sglebius    {
398290001Sglebius      UnityPrint(UnityStrNull);
399290001Sglebius    }
400290001Sglebius    UnityPrint(UnityStrWas);
401290001Sglebius    if (actual != NULL)
402290001Sglebius    {
403290001Sglebius        UNITY_OUTPUT_CHAR('\'');
404290001Sglebius        UnityPrint(actual);
405290001Sglebius        UNITY_OUTPUT_CHAR('\'');
406290001Sglebius    }
407290001Sglebius    else
408290001Sglebius    {
409290001Sglebius      UnityPrint(UnityStrNull);
410290001Sglebius    }
411290001Sglebius}
412290001Sglebius
413290001Sglebius//-----------------------------------------------
414290001Sglebius// Assertion & Control Helpers
415290001Sglebius//-----------------------------------------------
416290001Sglebius
417290001Sglebiusstatic int UnityCheckArraysForNull(UNITY_PTR_ATTRIBUTE const void* expected, UNITY_PTR_ATTRIBUTE const void* actual, const UNITY_LINE_TYPE lineNumber, const char* msg)
418290001Sglebius{
419290001Sglebius    //return true if they are both NULL
420290001Sglebius    if ((expected == NULL) && (actual == NULL))
421290001Sglebius        return 1;
422290001Sglebius
423290001Sglebius    //throw error if just expected is NULL
424290001Sglebius    if (expected == NULL)
425290001Sglebius    {
426290001Sglebius        UnityTestResultsFailBegin(lineNumber);
427290001Sglebius        UnityPrint(UnityStrNullPointerForExpected);
428290001Sglebius        UnityAddMsgIfSpecified(msg);
429290001Sglebius        UNITY_FAIL_AND_BAIL;
430290001Sglebius    }
431290001Sglebius
432290001Sglebius    //throw error if just actual is NULL
433290001Sglebius    if (actual == NULL)
434290001Sglebius    {
435290001Sglebius        UnityTestResultsFailBegin(lineNumber);
436290001Sglebius        UnityPrint(UnityStrNullPointerForActual);
437290001Sglebius        UnityAddMsgIfSpecified(msg);
438290001Sglebius        UNITY_FAIL_AND_BAIL;
439290001Sglebius    }
440290001Sglebius
441290001Sglebius    //return false if neither is NULL
442290001Sglebius    return 0;
443290001Sglebius}
444290001Sglebius
445290001Sglebius//-----------------------------------------------
446290001Sglebius// Assertion Functions
447290001Sglebius//-----------------------------------------------
448290001Sglebius
449290001Sglebiusvoid UnityAssertBits(const _U_SINT mask,
450290001Sglebius                     const _U_SINT expected,
451290001Sglebius                     const _U_SINT actual,
452290001Sglebius                     const char* msg,
453290001Sglebius                     const UNITY_LINE_TYPE lineNumber)
454290001Sglebius{
455290001Sglebius    UNITY_SKIP_EXECUTION;
456290001Sglebius
457290001Sglebius    if ((mask & expected) != (mask & actual))
458290001Sglebius    {
459290001Sglebius        UnityTestResultsFailBegin(lineNumber);
460290001Sglebius        UnityPrint(UnityStrExpected);
461290001Sglebius        UnityPrintMask((_U_UINT)mask, (_U_UINT)expected);
462290001Sglebius        UnityPrint(UnityStrWas);
463290001Sglebius        UnityPrintMask((_U_UINT)mask, (_U_UINT)actual);
464290001Sglebius        UnityAddMsgIfSpecified(msg);
465290001Sglebius        UNITY_FAIL_AND_BAIL;
466290001Sglebius    }
467290001Sglebius}
468290001Sglebius
469290001Sglebius//-----------------------------------------------
470290001Sglebiusvoid UnityAssertEqualNumber(const _U_SINT expected,
471290001Sglebius                            const _U_SINT actual,
472290001Sglebius                            const char* msg,
473290001Sglebius                            const UNITY_LINE_TYPE lineNumber,
474290001Sglebius                            const UNITY_DISPLAY_STYLE_T style)
475290001Sglebius{
476290001Sglebius    UNITY_SKIP_EXECUTION;
477290001Sglebius
478290001Sglebius    if (expected != actual)
479290001Sglebius    {
480290001Sglebius        UnityTestResultsFailBegin(lineNumber);
481290001Sglebius        UnityPrint(UnityStrExpected);
482290001Sglebius        UnityPrintNumberByStyle(expected, style);
483290001Sglebius        UnityPrint(UnityStrWas);
484290001Sglebius        UnityPrintNumberByStyle(actual, style);
485290001Sglebius        UnityAddMsgIfSpecified(msg);
486290001Sglebius        UNITY_FAIL_AND_BAIL;
487290001Sglebius    }
488290001Sglebius}
489290001Sglebius
490290001Sglebius//-----------------------------------------------
491290001Sglebiusvoid UnityAssertEqualIntArray(UNITY_PTR_ATTRIBUTE const void* expected,
492290001Sglebius                              UNITY_PTR_ATTRIBUTE const void* actual,
493290001Sglebius                              const _UU32 num_elements,
494290001Sglebius                              const char* msg,
495290001Sglebius                              const UNITY_LINE_TYPE lineNumber,
496290001Sglebius                              const UNITY_DISPLAY_STYLE_T style)
497290001Sglebius{
498290001Sglebius    _UU32 elements = num_elements;
499290001Sglebius    UNITY_PTR_ATTRIBUTE const _US8* ptr_exp = (UNITY_PTR_ATTRIBUTE const _US8*)expected;
500290001Sglebius    UNITY_PTR_ATTRIBUTE const _US8* ptr_act = (UNITY_PTR_ATTRIBUTE const _US8*)actual;
501290001Sglebius
502290001Sglebius    UNITY_SKIP_EXECUTION;
503290001Sglebius
504290001Sglebius    if (elements == 0)
505290001Sglebius    {
506290001Sglebius        UnityTestResultsFailBegin(lineNumber);
507290001Sglebius        UnityPrint(UnityStrPointless);
508290001Sglebius        UnityAddMsgIfSpecified(msg);
509290001Sglebius        UNITY_FAIL_AND_BAIL;
510290001Sglebius    }
511290001Sglebius
512290001Sglebius    if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE const void*)expected, (UNITY_PTR_ATTRIBUTE const void*)actual, lineNumber, msg) == 1)
513290001Sglebius        return;
514290001Sglebius
515290001Sglebius    // If style is UNITY_DISPLAY_STYLE_INT, we'll fall into the default case rather than the INT16 or INT32 (etc) case
516290001Sglebius    // as UNITY_DISPLAY_STYLE_INT includes a flag for UNITY_DISPLAY_RANGE_AUTO, which the width-specific
517290001Sglebius    // variants do not. Therefore remove this flag.
518290001Sglebius    switch(style & (UNITY_DISPLAY_STYLE_T)(~UNITY_DISPLAY_RANGE_AUTO))
519290001Sglebius    {
520290001Sglebius        case UNITY_DISPLAY_STYLE_HEX8:
521290001Sglebius        case UNITY_DISPLAY_STYLE_INT8:
522290001Sglebius        case UNITY_DISPLAY_STYLE_UINT8:
523290001Sglebius            while (elements--)
524290001Sglebius            {
525290001Sglebius                if (*ptr_exp != *ptr_act)
526290001Sglebius                {
527290001Sglebius                    UnityTestResultsFailBegin(lineNumber);
528290001Sglebius                    UnityPrint(UnityStrElement);
529290001Sglebius                    UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
530290001Sglebius                    UnityPrint(UnityStrExpected);
531290001Sglebius                    UnityPrintNumberByStyle(*ptr_exp, style);
532290001Sglebius                    UnityPrint(UnityStrWas);
533290001Sglebius                    UnityPrintNumberByStyle(*ptr_act, style);
534290001Sglebius                    UnityAddMsgIfSpecified(msg);
535290001Sglebius                    UNITY_FAIL_AND_BAIL;
536290001Sglebius                }
537290001Sglebius                ptr_exp += 1;
538290001Sglebius                ptr_act += 1;
539290001Sglebius            }
540290001Sglebius            break;
541290001Sglebius        case UNITY_DISPLAY_STYLE_HEX16:
542290001Sglebius        case UNITY_DISPLAY_STYLE_INT16:
543290001Sglebius        case UNITY_DISPLAY_STYLE_UINT16:
544290001Sglebius            while (elements--)
545290001Sglebius            {
546290001Sglebius                if (*(UNITY_PTR_ATTRIBUTE const _US16*)(void*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US16*)(void*)ptr_act)
547290001Sglebius                {
548290001Sglebius                    UnityTestResultsFailBegin(lineNumber);
549290001Sglebius                    UnityPrint(UnityStrElement);
550290001Sglebius                    UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
551290001Sglebius                    UnityPrint(UnityStrExpected);
552290001Sglebius                    UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)(void*)ptr_exp, style);
553290001Sglebius                    UnityPrint(UnityStrWas);
554290001Sglebius                    UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)(void*)ptr_act, style);
555290001Sglebius                    UnityAddMsgIfSpecified(msg);
556290001Sglebius                    UNITY_FAIL_AND_BAIL;
557290001Sglebius                }
558290001Sglebius                ptr_exp += 2;
559290001Sglebius                ptr_act += 2;
560290001Sglebius            }
561290001Sglebius            break;
562290001Sglebius#ifdef UNITY_SUPPORT_64
563290001Sglebius        case UNITY_DISPLAY_STYLE_HEX64:
564290001Sglebius        case UNITY_DISPLAY_STYLE_INT64:
565290001Sglebius        case UNITY_DISPLAY_STYLE_UINT64:
566290001Sglebius            while (elements--)
567290001Sglebius            {
568290001Sglebius                if (*(UNITY_PTR_ATTRIBUTE const _US64*)(void*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US64*)(void*)ptr_act)
569290001Sglebius                {
570290001Sglebius                    UnityTestResultsFailBegin(lineNumber);
571290001Sglebius                    UnityPrint(UnityStrElement);
572290001Sglebius                    UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
573290001Sglebius                    UnityPrint(UnityStrExpected);
574290001Sglebius                    UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)(void*)ptr_exp, style);
575290001Sglebius                    UnityPrint(UnityStrWas);
576290001Sglebius                    UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)(void*)ptr_act, style);
577290001Sglebius                    UnityAddMsgIfSpecified(msg);
578290001Sglebius                    UNITY_FAIL_AND_BAIL;
579290001Sglebius                }
580290001Sglebius                ptr_exp += 8;
581290001Sglebius                ptr_act += 8;
582290001Sglebius            }
583290001Sglebius            break;
584290001Sglebius#endif
585290001Sglebius        default:
586290001Sglebius            while (elements--)
587290001Sglebius            {
588290001Sglebius                if (*(UNITY_PTR_ATTRIBUTE const _US32*)(void*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US32*)(void*)ptr_act)
589290001Sglebius                {
590290001Sglebius                    UnityTestResultsFailBegin(lineNumber);
591290001Sglebius                    UnityPrint(UnityStrElement);
592290001Sglebius                    UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
593290001Sglebius                    UnityPrint(UnityStrExpected);
594290001Sglebius                    UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)(void*)ptr_exp, style);
595290001Sglebius                    UnityPrint(UnityStrWas);
596290001Sglebius                    UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)(void*)ptr_act, style);
597290001Sglebius                    UnityAddMsgIfSpecified(msg);
598290001Sglebius                    UNITY_FAIL_AND_BAIL;
599290001Sglebius                }
600290001Sglebius                ptr_exp += 4;
601290001Sglebius                ptr_act += 4;
602290001Sglebius            }
603290001Sglebius            break;
604290001Sglebius    }
605290001Sglebius}
606290001Sglebius
607290001Sglebius//-----------------------------------------------
608290001Sglebius#ifndef UNITY_EXCLUDE_FLOAT
609290001Sglebiusvoid UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected,
610290001Sglebius                                UNITY_PTR_ATTRIBUTE const _UF* actual,
611290001Sglebius                                const _UU32 num_elements,
612290001Sglebius                                const char* msg,
613290001Sglebius                                const UNITY_LINE_TYPE lineNumber)
614290001Sglebius{
615290001Sglebius    _UU32 elements = num_elements;
616290001Sglebius    UNITY_PTR_ATTRIBUTE const _UF* ptr_expected = expected;
617290001Sglebius    UNITY_PTR_ATTRIBUTE const _UF* ptr_actual = actual;
618290001Sglebius    _UF diff, tol;
619290001Sglebius
620290001Sglebius    UNITY_SKIP_EXECUTION;
621290001Sglebius
622290001Sglebius    if (elements == 0)
623290001Sglebius    {
624290001Sglebius        UnityTestResultsFailBegin(lineNumber);
625290001Sglebius        UnityPrint(UnityStrPointless);
626290001Sglebius        UnityAddMsgIfSpecified(msg);
627290001Sglebius        UNITY_FAIL_AND_BAIL;
628290001Sglebius    }
629290001Sglebius
630290001Sglebius    if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE const void*)expected, (UNITY_PTR_ATTRIBUTE const void*)actual, lineNumber, msg) == 1)
631290001Sglebius        return;
632290001Sglebius
633290001Sglebius    while (elements--)
634290001Sglebius    {
635290001Sglebius        diff = *ptr_expected - *ptr_actual;
636290001Sglebius        if (diff < 0.0f)
637290001Sglebius          diff = 0.0f - diff;
638290001Sglebius        tol = UNITY_FLOAT_PRECISION * *ptr_expected;
639290001Sglebius        if (tol < 0.0f)
640290001Sglebius            tol = 0.0f - tol;
641290001Sglebius
642290001Sglebius        //This first part of this condition will catch any NaN or Infinite values
643290001Sglebius        if ((diff * 0.0f != 0.0f) || (diff > tol))
644290001Sglebius        {
645290001Sglebius            UnityTestResultsFailBegin(lineNumber);
646290001Sglebius            UnityPrint(UnityStrElement);
647290001Sglebius            UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
648290001Sglebius#ifdef UNITY_FLOAT_VERBOSE
649290001Sglebius            UnityPrint(UnityStrExpected);
650290001Sglebius            UnityPrintFloat(*ptr_expected);
651290001Sglebius            UnityPrint(UnityStrWas);
652290001Sglebius            UnityPrintFloat(*ptr_actual);
653290001Sglebius#else
654290001Sglebius            UnityPrint(UnityStrDelta);
655290001Sglebius#endif
656290001Sglebius            UnityAddMsgIfSpecified(msg);
657290001Sglebius            UNITY_FAIL_AND_BAIL;
658290001Sglebius        }
659290001Sglebius        ptr_expected++;
660290001Sglebius        ptr_actual++;
661290001Sglebius    }
662290001Sglebius}
663290001Sglebius
664290001Sglebius//-----------------------------------------------
665290001Sglebiusvoid UnityAssertFloatsWithin(const _UF delta,
666290001Sglebius                             const _UF expected,
667290001Sglebius                             const _UF actual,
668290001Sglebius                             const char* msg,
669290001Sglebius                             const UNITY_LINE_TYPE lineNumber)
670290001Sglebius{
671290001Sglebius    _UF diff = actual - expected;
672290001Sglebius    _UF pos_delta = delta;
673290001Sglebius
674290001Sglebius    UNITY_SKIP_EXECUTION;
675290001Sglebius
676290001Sglebius    if (diff < 0.0f)
677290001Sglebius    {
678290001Sglebius        diff = 0.0f - diff;
679290001Sglebius    }
680290001Sglebius    if (pos_delta < 0.0f)
681290001Sglebius    {
682290001Sglebius        pos_delta = 0.0f - pos_delta;
683290001Sglebius    }
684290001Sglebius
685290001Sglebius    //This first part of this condition will catch any NaN or Infinite values
686290001Sglebius    if ((diff * 0.0f != 0.0f) || (pos_delta < diff))
687290001Sglebius    {
688290001Sglebius        UnityTestResultsFailBegin(lineNumber);
689290001Sglebius#ifdef UNITY_FLOAT_VERBOSE
690290001Sglebius        UnityPrint(UnityStrExpected);
691290001Sglebius        UnityPrintFloat(expected);
692290001Sglebius        UnityPrint(UnityStrWas);
693290001Sglebius        UnityPrintFloat(actual);
694290001Sglebius#else
695290001Sglebius        UnityPrint(UnityStrDelta);
696290001Sglebius#endif
697290001Sglebius        UnityAddMsgIfSpecified(msg);
698290001Sglebius        UNITY_FAIL_AND_BAIL;
699290001Sglebius    }
700290001Sglebius}
701290001Sglebius
702290001Sglebius//-----------------------------------------------
703290001Sglebiusvoid UnityAssertFloatSpecial(const _UF actual,
704290001Sglebius                             const char* msg,
705290001Sglebius                             const UNITY_LINE_TYPE lineNumber,
706290001Sglebius                             const UNITY_FLOAT_TRAIT_T style)
707290001Sglebius{
708290001Sglebius    const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet };
709290001Sglebius    _U_SINT should_be_trait   = ((_U_SINT)style & 1);
710290001Sglebius    _U_SINT is_trait          = !should_be_trait;
711290001Sglebius    _U_SINT trait_index       = style >> 1;
712290001Sglebius
713290001Sglebius    UNITY_SKIP_EXECUTION;
714290001Sglebius
715290001Sglebius    switch(style)
716290001Sglebius    {
717290001Sglebius        //To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly
718290001Sglebius        //We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise
719290001Sglebius        case UNITY_FLOAT_IS_INF:
720290001Sglebius        case UNITY_FLOAT_IS_NOT_INF:
721290001Sglebius            is_trait = ((1.0f / f_zero) == actual) ? 1 : 0;
722290001Sglebius            break;
723290001Sglebius        case UNITY_FLOAT_IS_NEG_INF:
724290001Sglebius        case UNITY_FLOAT_IS_NOT_NEG_INF:
725290001Sglebius            is_trait = ((-1.0f / f_zero) == actual) ? 1 : 0;
726290001Sglebius            break;
727290001Sglebius
728290001Sglebius        //NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN.
729290001Sglebius        case UNITY_FLOAT_IS_NAN:
730290001Sglebius        case UNITY_FLOAT_IS_NOT_NAN:
731290001Sglebius            is_trait = (actual == actual) ? 0 : 1;
732290001Sglebius            break;
733290001Sglebius
734290001Sglebius        //A determinate number is non infinite and not NaN. (therefore the opposite of the two above)
735290001Sglebius        case UNITY_FLOAT_IS_DET:
736290001Sglebius        case UNITY_FLOAT_IS_NOT_DET:
737290001Sglebius            if ( (actual != actual) || ((1.0f / f_zero) == actual) || ((-1.0f / f_zero) == actual) )
738290001Sglebius                is_trait = 0;
739290001Sglebius            else
740290001Sglebius                is_trait = 1;
741290001Sglebius            break;
742290001Sglebius	default:
743290001Sglebius	    ;
744290001Sglebius    }
745290001Sglebius
746290001Sglebius    if (is_trait != should_be_trait)
747290001Sglebius    {
748290001Sglebius        UnityTestResultsFailBegin(lineNumber);
749290001Sglebius        UnityPrint(UnityStrExpected);
750290001Sglebius        if (!should_be_trait)
751290001Sglebius            UnityPrint(UnityStrNot);
752290001Sglebius        UnityPrint(trait_names[trait_index]);
753290001Sglebius        UnityPrint(UnityStrWas);
754290001Sglebius#ifdef UNITY_FLOAT_VERBOSE
755290001Sglebius        UnityPrintFloat(actual);
756290001Sglebius#else
757290001Sglebius        if (should_be_trait)
758290001Sglebius            UnityPrint(UnityStrNot);
759290001Sglebius        UnityPrint(trait_names[trait_index]);
760290001Sglebius#endif
761290001Sglebius        UnityAddMsgIfSpecified(msg);
762290001Sglebius        UNITY_FAIL_AND_BAIL;
763290001Sglebius    }
764290001Sglebius}
765290001Sglebius
766290001Sglebius#endif //not UNITY_EXCLUDE_FLOAT
767290001Sglebius
768290001Sglebius//-----------------------------------------------
769290001Sglebius#ifndef UNITY_EXCLUDE_DOUBLE
770290001Sglebiusvoid UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected,
771290001Sglebius                                 UNITY_PTR_ATTRIBUTE const _UD* actual,
772290001Sglebius                                 const _UU32 num_elements,
773290001Sglebius                                 const char* msg,
774290001Sglebius                                 const UNITY_LINE_TYPE lineNumber)
775290001Sglebius{
776290001Sglebius    _UU32 elements = num_elements;
777290001Sglebius    UNITY_PTR_ATTRIBUTE const _UD* ptr_expected = expected;
778290001Sglebius    UNITY_PTR_ATTRIBUTE const _UD* ptr_actual = actual;
779290001Sglebius    _UD diff, tol;
780290001Sglebius
781290001Sglebius    UNITY_SKIP_EXECUTION;
782290001Sglebius
783290001Sglebius    if (elements == 0)
784290001Sglebius    {
785290001Sglebius        UnityTestResultsFailBegin(lineNumber);
786290001Sglebius        UnityPrint(UnityStrPointless);
787290001Sglebius        UnityAddMsgIfSpecified(msg);
788290001Sglebius        UNITY_FAIL_AND_BAIL;
789290001Sglebius    }
790290001Sglebius
791290001Sglebius    if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE void*)expected, (UNITY_PTR_ATTRIBUTE void*)actual, lineNumber, msg) == 1)
792290001Sglebius        return;
793290001Sglebius
794290001Sglebius    while (elements--)
795290001Sglebius    {
796290001Sglebius        diff = *ptr_expected - *ptr_actual;
797290001Sglebius        if (diff < 0.0)
798290001Sglebius          diff = 0.0 - diff;
799290001Sglebius        tol = UNITY_DOUBLE_PRECISION * *ptr_expected;
800290001Sglebius        if (tol < 0.0)
801290001Sglebius            tol = 0.0 - tol;
802290001Sglebius
803290001Sglebius        //This first part of this condition will catch any NaN or Infinite values
804290001Sglebius        if ((diff * 0.0 != 0.0) || (diff > tol))
805290001Sglebius        {
806290001Sglebius            UnityTestResultsFailBegin(lineNumber);
807290001Sglebius            UnityPrint(UnityStrElement);
808290001Sglebius            UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
809290001Sglebius#ifdef UNITY_DOUBLE_VERBOSE
810290001Sglebius            UnityPrint(UnityStrExpected);
811290001Sglebius            UnityPrintFloat((float)(*ptr_expected));
812290001Sglebius            UnityPrint(UnityStrWas);
813290001Sglebius            UnityPrintFloat((float)(*ptr_actual));
814290001Sglebius#else
815290001Sglebius            UnityPrint(UnityStrDelta);
816290001Sglebius#endif
817290001Sglebius            UnityAddMsgIfSpecified(msg);
818290001Sglebius            UNITY_FAIL_AND_BAIL;
819290001Sglebius        }
820290001Sglebius        ptr_expected++;
821290001Sglebius        ptr_actual++;
822290001Sglebius    }
823290001Sglebius}
824290001Sglebius
825290001Sglebius//-----------------------------------------------
826290001Sglebiusvoid UnityAssertDoublesWithin(const _UD delta,
827290001Sglebius                              const _UD expected,
828290001Sglebius                              const _UD actual,
829290001Sglebius                              const char* msg,
830290001Sglebius                              const UNITY_LINE_TYPE lineNumber)
831290001Sglebius{
832290001Sglebius    _UD diff = actual - expected;
833290001Sglebius    _UD pos_delta = delta;
834290001Sglebius
835290001Sglebius    UNITY_SKIP_EXECUTION;
836290001Sglebius
837290001Sglebius    if (diff < 0.0)
838290001Sglebius    {
839290001Sglebius        diff = 0.0 - diff;
840290001Sglebius    }
841290001Sglebius    if (pos_delta < 0.0)
842290001Sglebius    {
843290001Sglebius        pos_delta = 0.0 - pos_delta;
844290001Sglebius    }
845290001Sglebius
846290001Sglebius    //This first part of this condition will catch any NaN or Infinite values
847290001Sglebius    if ((diff * 0.0 != 0.0) || (pos_delta < diff))
848290001Sglebius    {
849290001Sglebius        UnityTestResultsFailBegin(lineNumber);
850290001Sglebius#ifdef UNITY_DOUBLE_VERBOSE
851290001Sglebius        UnityPrint(UnityStrExpected);
852290001Sglebius        UnityPrintFloat((float)expected);
853290001Sglebius        UnityPrint(UnityStrWas);
854290001Sglebius        UnityPrintFloat((float)actual);
855290001Sglebius#else
856290001Sglebius        UnityPrint(UnityStrDelta);
857290001Sglebius#endif
858290001Sglebius        UnityAddMsgIfSpecified(msg);
859290001Sglebius        UNITY_FAIL_AND_BAIL;
860290001Sglebius    }
861290001Sglebius}
862290001Sglebius
863290001Sglebius//-----------------------------------------------
864290001Sglebius
865290001Sglebiusvoid UnityAssertDoubleSpecial(const _UD actual,
866290001Sglebius                              const char* msg,
867290001Sglebius                              const UNITY_LINE_TYPE lineNumber,
868290001Sglebius                              const UNITY_FLOAT_TRAIT_T style)
869290001Sglebius{
870290001Sglebius    const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet };
871290001Sglebius    _U_SINT should_be_trait   = ((_U_SINT)style & 1);
872290001Sglebius    _U_SINT is_trait          = !should_be_trait;
873290001Sglebius    _U_SINT trait_index       = style >> 1;
874290001Sglebius
875290001Sglebius    UNITY_SKIP_EXECUTION;
876290001Sglebius
877290001Sglebius    switch(style)
878290001Sglebius    {
879290001Sglebius        //To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly
880290001Sglebius        //We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise
881290001Sglebius        case UNITY_FLOAT_IS_INF:
882290001Sglebius        case UNITY_FLOAT_IS_NOT_INF:
883290001Sglebius            is_trait = ((1.0 / d_zero) == actual) ? 1 : 0;
884290001Sglebius            break;
885290001Sglebius        case UNITY_FLOAT_IS_NEG_INF:
886290001Sglebius        case UNITY_FLOAT_IS_NOT_NEG_INF:
887290001Sglebius            is_trait = ((-1.0 / d_zero) == actual) ? 1 : 0;
888290001Sglebius            break;
889290001Sglebius
890290001Sglebius        //NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN.
891290001Sglebius        case UNITY_FLOAT_IS_NAN:
892290001Sglebius        case UNITY_FLOAT_IS_NOT_NAN:
893290001Sglebius            is_trait = (actual == actual) ? 0 : 1;
894290001Sglebius            break;
895290001Sglebius
896290001Sglebius        //A determinate number is non infinite and not NaN. (therefore the opposite of the two above)
897290001Sglebius        case UNITY_FLOAT_IS_DET:
898290001Sglebius        case UNITY_FLOAT_IS_NOT_DET:
899290001Sglebius            if ( (actual != actual) || ((1.0 / d_zero) == actual) || ((-1.0 / d_zero) == actual) )
900290001Sglebius                is_trait = 0;
901290001Sglebius            else
902290001Sglebius                is_trait = 1;
903290001Sglebius            break;
904290001Sglebius	default:
905290001Sglebius	    ;
906290001Sglebius    }
907290001Sglebius
908290001Sglebius    if (is_trait != should_be_trait)
909290001Sglebius    {
910290001Sglebius        UnityTestResultsFailBegin(lineNumber);
911290001Sglebius        UnityPrint(UnityStrExpected);
912290001Sglebius        if (!should_be_trait)
913290001Sglebius            UnityPrint(UnityStrNot);
914290001Sglebius        UnityPrint(trait_names[trait_index]);
915290001Sglebius        UnityPrint(UnityStrWas);
916290001Sglebius#ifdef UNITY_DOUBLE_VERBOSE
917290001Sglebius        UnityPrintFloat(actual);
918290001Sglebius#else
919290001Sglebius        if (should_be_trait)
920290001Sglebius            UnityPrint(UnityStrNot);
921290001Sglebius        UnityPrint(trait_names[trait_index]);
922290001Sglebius#endif
923290001Sglebius        UnityAddMsgIfSpecified(msg);
924290001Sglebius        UNITY_FAIL_AND_BAIL;
925290001Sglebius    }
926290001Sglebius}
927290001Sglebius
928290001Sglebius
929290001Sglebius#endif // not UNITY_EXCLUDE_DOUBLE
930290001Sglebius
931290001Sglebius//-----------------------------------------------
932290001Sglebiusvoid UnityAssertNumbersWithin( const _U_SINT delta,
933290001Sglebius                               const _U_SINT expected,
934290001Sglebius                               const _U_SINT actual,
935290001Sglebius                               const char* msg,
936290001Sglebius                               const UNITY_LINE_TYPE lineNumber,
937290001Sglebius                               const UNITY_DISPLAY_STYLE_T style)
938290001Sglebius{
939290001Sglebius    UNITY_SKIP_EXECUTION;
940290001Sglebius
941290001Sglebius    if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
942290001Sglebius    {
943290001Sglebius        if (actual > expected)
944290001Sglebius          Unity.CurrentTestFailed = ((actual - expected) > delta);
945290001Sglebius        else
946290001Sglebius          Unity.CurrentTestFailed = ((expected - actual) > delta);
947290001Sglebius    }
948290001Sglebius    else
949290001Sglebius    {
950290001Sglebius        if ((_U_UINT)actual > (_U_UINT)expected)
951290001Sglebius            Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > (_U_UINT)delta);
952290001Sglebius        else
953290001Sglebius            Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > (_U_UINT)delta);
954290001Sglebius    }
955290001Sglebius
956290001Sglebius    if (Unity.CurrentTestFailed)
957290001Sglebius    {
958290001Sglebius        UnityTestResultsFailBegin(lineNumber);
959290001Sglebius        UnityPrint(UnityStrDelta);
960290001Sglebius        UnityPrintNumberByStyle(delta, style);
961290001Sglebius        UnityPrint(UnityStrExpected);
962290001Sglebius        UnityPrintNumberByStyle(expected, style);
963290001Sglebius        UnityPrint(UnityStrWas);
964290001Sglebius        UnityPrintNumberByStyle(actual, style);
965290001Sglebius        UnityAddMsgIfSpecified(msg);
966290001Sglebius        UNITY_FAIL_AND_BAIL;
967290001Sglebius    }
968290001Sglebius}
969290001Sglebius
970290001Sglebius//-----------------------------------------------
971290001Sglebiusvoid UnityAssertEqualString(const char* expected,
972290001Sglebius                            const char* actual,
973290001Sglebius                            const char* msg,
974290001Sglebius                            const UNITY_LINE_TYPE lineNumber)
975290001Sglebius{
976290001Sglebius    _UU32 i;
977290001Sglebius
978290001Sglebius    UNITY_SKIP_EXECUTION;
979290001Sglebius
980290001Sglebius    // if both pointers not null compare the strings
981290001Sglebius    if (expected && actual)
982290001Sglebius    {
983290001Sglebius        for (i = 0; expected[i] || actual[i]; i++)
984290001Sglebius        {
985290001Sglebius            if (expected[i] != actual[i])
986290001Sglebius            {
987290001Sglebius                Unity.CurrentTestFailed = 1;
988290001Sglebius                break;
989290001Sglebius            }
990290001Sglebius        }
991290001Sglebius    }
992290001Sglebius    else
993290001Sglebius    { // handle case of one pointers being null (if both null, test should pass)
994290001Sglebius        if (expected != actual)
995290001Sglebius        {
996290001Sglebius            Unity.CurrentTestFailed = 1;
997290001Sglebius        }
998290001Sglebius    }
999290001Sglebius
1000290001Sglebius    if (Unity.CurrentTestFailed)
1001290001Sglebius    {
1002290001Sglebius      UnityTestResultsFailBegin(lineNumber);
1003290001Sglebius      UnityPrintExpectedAndActualStrings(expected, actual);
1004290001Sglebius      UnityAddMsgIfSpecified(msg);
1005290001Sglebius      UNITY_FAIL_AND_BAIL;
1006290001Sglebius    }
1007290001Sglebius}
1008290001Sglebius
1009290001Sglebius//-----------------------------------------------
1010290001Sglebiusvoid UnityAssertEqualStringArray( const char** expected,
1011290001Sglebius                                  const char** actual,
1012290001Sglebius                                  const _UU32 num_elements,
1013290001Sglebius                                  const char* msg,
1014290001Sglebius                                  const UNITY_LINE_TYPE lineNumber)
1015290001Sglebius{
1016290001Sglebius    _UU32 i, j = 0;
1017290001Sglebius
1018290001Sglebius    UNITY_SKIP_EXECUTION;
1019290001Sglebius
1020290001Sglebius    // if no elements, it's an error
1021290001Sglebius    if (num_elements == 0)
1022290001Sglebius    {
1023290001Sglebius        UnityTestResultsFailBegin(lineNumber);
1024290001Sglebius        UnityPrint(UnityStrPointless);
1025290001Sglebius        UnityAddMsgIfSpecified(msg);
1026290001Sglebius        UNITY_FAIL_AND_BAIL;
1027290001Sglebius    }
1028290001Sglebius
1029290001Sglebius    if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE void*)expected, (UNITY_PTR_ATTRIBUTE void*)actual, lineNumber, msg) == 1)
1030290001Sglebius        return;
1031290001Sglebius
1032290001Sglebius    do
1033290001Sglebius    {
1034290001Sglebius        // if both pointers not null compare the strings
1035290001Sglebius        if (expected[j] && actual[j])
1036290001Sglebius        {
1037290001Sglebius            for (i = 0; expected[j][i] || actual[j][i]; i++)
1038290001Sglebius            {
1039290001Sglebius                if (expected[j][i] != actual[j][i])
1040290001Sglebius                {
1041290001Sglebius                    Unity.CurrentTestFailed = 1;
1042290001Sglebius                    break;
1043290001Sglebius                }
1044290001Sglebius            }
1045290001Sglebius        }
1046290001Sglebius        else
1047290001Sglebius        { // handle case of one pointers being null (if both null, test should pass)
1048290001Sglebius            if (expected[j] != actual[j])
1049290001Sglebius            {
1050290001Sglebius                Unity.CurrentTestFailed = 1;
1051290001Sglebius            }
1052290001Sglebius        }
1053290001Sglebius
1054290001Sglebius        if (Unity.CurrentTestFailed)
1055290001Sglebius        {
1056290001Sglebius            UnityTestResultsFailBegin(lineNumber);
1057290001Sglebius            if (num_elements > 1)
1058290001Sglebius            {
1059290001Sglebius                UnityPrint(UnityStrElement);
1060290001Sglebius                UnityPrintNumberByStyle((j), UNITY_DISPLAY_STYLE_UINT);
1061290001Sglebius            }
1062290001Sglebius            UnityPrintExpectedAndActualStrings((const char*)(expected[j]), (const char*)(actual[j]));
1063290001Sglebius            UnityAddMsgIfSpecified(msg);
1064290001Sglebius            UNITY_FAIL_AND_BAIL;
1065290001Sglebius        }
1066290001Sglebius    } while (++j < num_elements);
1067290001Sglebius}
1068290001Sglebius
1069290001Sglebius//-----------------------------------------------
1070290001Sglebiusvoid UnityAssertEqualMemory( UNITY_PTR_ATTRIBUTE const void* expected,
1071290001Sglebius                             UNITY_PTR_ATTRIBUTE const void* actual,
1072290001Sglebius                             const _UU32 length,
1073290001Sglebius                             const _UU32 num_elements,
1074290001Sglebius                             const char* msg,
1075290001Sglebius                             const UNITY_LINE_TYPE lineNumber)
1076290001Sglebius{
1077290001Sglebius    UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected;
1078290001Sglebius    UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual;
1079290001Sglebius    _UU32 elements = num_elements;
1080290001Sglebius    _UU32 bytes;
1081290001Sglebius
1082290001Sglebius    UNITY_SKIP_EXECUTION;
1083290001Sglebius
1084290001Sglebius    if ((elements == 0) || (length == 0))
1085290001Sglebius    {
1086290001Sglebius        UnityTestResultsFailBegin(lineNumber);
1087290001Sglebius        UnityPrint(UnityStrPointless);
1088290001Sglebius        UnityAddMsgIfSpecified(msg);
1089290001Sglebius        UNITY_FAIL_AND_BAIL;
1090290001Sglebius    }
1091290001Sglebius
1092290001Sglebius    if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE const void*)expected, (UNITY_PTR_ATTRIBUTE const void*)actual, lineNumber, msg) == 1)
1093290001Sglebius        return;
1094290001Sglebius
1095290001Sglebius    while (elements--)
1096290001Sglebius    {
1097290001Sglebius        /////////////////////////////////////
1098290001Sglebius        bytes = length;
1099290001Sglebius        while (bytes--)
1100290001Sglebius        {
1101290001Sglebius            if (*ptr_exp != *ptr_act)
1102290001Sglebius            {
1103290001Sglebius                UnityTestResultsFailBegin(lineNumber);
1104290001Sglebius                UnityPrint(UnityStrMemory);
1105290001Sglebius                if (num_elements > 1)
1106290001Sglebius                {
1107290001Sglebius                    UnityPrint(UnityStrElement);
1108290001Sglebius                    UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
1109290001Sglebius                }
1110290001Sglebius                UnityPrint(UnityStrByte);
1111290001Sglebius                UnityPrintNumberByStyle((length - bytes - 1), UNITY_DISPLAY_STYLE_UINT);
1112290001Sglebius                UnityPrint(UnityStrExpected);
1113290001Sglebius                UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8);
1114290001Sglebius                UnityPrint(UnityStrWas);
1115290001Sglebius                UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8);
1116290001Sglebius                UnityAddMsgIfSpecified(msg);
1117290001Sglebius                UNITY_FAIL_AND_BAIL;
1118290001Sglebius            }
1119290001Sglebius            ptr_exp += 1;
1120290001Sglebius            ptr_act += 1;
1121290001Sglebius        }
1122290001Sglebius        /////////////////////////////////////
1123290001Sglebius
1124290001Sglebius    }
1125290001Sglebius}
1126290001Sglebius
1127290001Sglebius//-----------------------------------------------
1128290001Sglebius// Control Functions
1129290001Sglebius//-----------------------------------------------
1130290001Sglebius
1131290001Sglebiusvoid UnityFail(const char* msg, const UNITY_LINE_TYPE line)
1132290001Sglebius{
1133290001Sglebius    UNITY_SKIP_EXECUTION;
1134290001Sglebius
1135290001Sglebius    UnityTestResultsBegin(Unity.TestFile, line);
1136290001Sglebius    UnityPrintFail();
1137290001Sglebius    if (msg != NULL)
1138290001Sglebius    {
1139290001Sglebius      UNITY_OUTPUT_CHAR(':');
1140290001Sglebius      if (msg[0] != ' ')
1141290001Sglebius      {
1142290001Sglebius        UNITY_OUTPUT_CHAR(' ');
1143290001Sglebius      }
1144290001Sglebius      UnityPrint(msg);
1145290001Sglebius    }
1146290001Sglebius    UNITY_FAIL_AND_BAIL;
1147290001Sglebius}
1148290001Sglebius
1149290001Sglebius//-----------------------------------------------
1150290001Sglebiusvoid UnityIgnore(const char* msg, const UNITY_LINE_TYPE line)
1151290001Sglebius{
1152290001Sglebius    UNITY_SKIP_EXECUTION;
1153290001Sglebius
1154290001Sglebius    UnityTestResultsBegin(Unity.TestFile, line);
1155290001Sglebius    UnityPrint(UnityStrIgnore);
1156290001Sglebius    if (msg != NULL)
1157290001Sglebius    {
1158290001Sglebius      UNITY_OUTPUT_CHAR(':');
1159290001Sglebius      UNITY_OUTPUT_CHAR(' ');
1160290001Sglebius      UnityPrint(msg);
1161290001Sglebius    }
1162290001Sglebius    UNITY_IGNORE_AND_BAIL;
1163290001Sglebius}
1164290001Sglebius
1165290001Sglebius//----------------------------------------------
1166290001Sglebius
1167290001Sglebiusvoid UnityExpectFail(){
1168290001Sglebius
1169290001Sglebius	Unity.isExpectingFail = 1;
1170290001Sglebius
1171290001Sglebius}
1172290001Sglebius
1173290001Sglebiusvoid UnityExpectFailMessage(const char* msg, const UNITY_LINE_TYPE line ){
1174290001Sglebius
1175290001Sglebius	Unity.isExpectingFail = 1;
1176290001Sglebius	  if (msg != NULL)
1177290001Sglebius    {
1178290001Sglebius		Unity.XFAILMessage = msg;
1179290001Sglebius    }
1180290001Sglebius}
1181290001Sglebius
1182290001Sglebius//-----------------------------------------------
1183290001Sglebius#if defined(UNITY_WEAK_ATTRIBUTE)
1184290001Sglebius    void setUp(void);
1185290001Sglebius    void tearDown(void);
1186290001Sglebius    UNITY_WEAK_ATTRIBUTE void setUp(void) { }
1187290001Sglebius    UNITY_WEAK_ATTRIBUTE void tearDown(void) { }
1188290001Sglebius#elif defined(UNITY_WEAK_PRAGMA)
1189290001Sglebius#   pragma weak setUp
1190290001Sglebius    void setUp(void);
1191290001Sglebius#   pragma weak tearDown
1192290001Sglebius    void tearDown(void);
1193290001Sglebius#else
1194290001Sglebius    void setUp(void);
1195290001Sglebius    void tearDown(void);
1196290001Sglebius#endif
1197290001Sglebius
1198290001Sglebius//-----------------------------------------------
1199290001Sglebiusvoid UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum)
1200290001Sglebius{
1201290001Sglebius    Unity.CurrentTestName = FuncName;
1202290001Sglebius    Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum;
1203290001Sglebius    Unity.NumberOfTests++;
1204290001Sglebius
1205290001Sglebius    if (TEST_PROTECT())
1206290001Sglebius    {
1207290001Sglebius        setUp();
1208290001Sglebius        Func();
1209290001Sglebius    }
1210290001Sglebius    if (TEST_PROTECT() && !(Unity.CurrentTestIgnored))
1211290001Sglebius    {
1212290001Sglebius        tearDown();
1213290001Sglebius    }
1214290001Sglebius
1215290001Sglebius    UnityConcludeTest();
1216290001Sglebius}
1217290001Sglebius
1218290001Sglebius
1219290001Sglebius//-----------------------------------------------
1220290001Sglebiusvoid UnityBegin(const char* filename)
1221290001Sglebius{
1222290001Sglebius    Unity.TestFile = filename;
1223290001Sglebius    Unity.CurrentTestName = NULL;
1224290001Sglebius    Unity.CurrentTestLineNumber = 0;
1225290001Sglebius    Unity.NumberOfTests = 0;
1226290001Sglebius    Unity.TestFailures = 0;
1227290001Sglebius    Unity.TestIgnores = 0;
1228290001Sglebius    Unity.CurrentTestFailed = 0;
1229290001Sglebius    Unity.CurrentTestIgnored = 0;
1230290001Sglebius    Unity.TestXFAILS = 0;
1231290001Sglebius    Unity.isExpectingFail = 0;
1232290001Sglebius    Unity.TestPasses = 0;
1233290001Sglebius    Unity.TestXPASSES = 0;
1234290001Sglebius    Unity.XFAILMessage = NULL;
1235290001Sglebius
1236290001Sglebius    UNITY_OUTPUT_START();
1237290001Sglebius}
1238290001Sglebius
1239290001Sglebius
1240290001Sglebius//-----------------------------------------------
1241290001Sglebiusint UnityEnd(void)
1242290001Sglebius{
1243290001Sglebius    UNITY_PRINT_EOL;
1244290001Sglebius    UnityPrint(UnityStrBreaker);
1245290001Sglebius    UNITY_PRINT_EOL;
1246290001Sglebius    UnityPrintNumber((_U_SINT)(Unity.NumberOfTests));
1247290001Sglebius    UnityPrint(UnityStrResultsTests);
1248290001Sglebius    UNITY_PRINT_EOL;
1249290001Sglebius    UnityPrintNumber((_U_SINT)(Unity.TestPasses));
1250290001Sglebius    UnityPrint(UnityStrResultsPass);
1251290001Sglebius    UNITY_PRINT_EOL;
1252290001Sglebius    UnityPrintNumber((_U_SINT)(Unity.TestXFAILS));
1253290001Sglebius    UnityPrint(UnityStrResultsXFAIL);
1254290001Sglebius    UNITY_PRINT_EOL;
1255290001Sglebius    UnityPrintNumber((_U_SINT)(Unity.TestFailures));
1256290001Sglebius    UnityPrint(UnityStrResultsFailures);
1257290001Sglebius    UNITY_PRINT_EOL;
1258290001Sglebius    UnityPrintNumber((_U_SINT)(Unity.TestXPASSES));
1259290001Sglebius    UnityPrint(UnityStrResultsXPASS);
1260290001Sglebius    UNITY_PRINT_EOL;
1261290001Sglebius    UnityPrintNumber((_U_SINT)(Unity.TestIgnores));
1262290001Sglebius    UnityPrint(UnityStrResultsIgnored);
1263290001Sglebius    UNITY_PRINT_EOL;
1264290001Sglebius
1265290001Sglebius    UNITY_PRINT_EOL;
1266290001Sglebius    if (Unity.TestFailures == 0U && Unity.TestXPASSES == 0U)
1267290001Sglebius    {
1268290001Sglebius        UnityPrintOk();
1269290001Sglebius    }
1270290001Sglebius    else
1271290001Sglebius    {
1272290001Sglebius        UnityPrintFail();
1273290001Sglebius    }
1274290001Sglebius    UNITY_PRINT_EOL;
1275290001Sglebius    UNITY_OUTPUT_COMPLETE();
1276290001Sglebius    return (int)(Unity.TestFailures);
1277290001Sglebius}
1278290001Sglebius
1279290001Sglebius
1280290001Sglebius//-----------------------------------------------
1281