1 /* =========================================================================
2     Unity Project - A Test Framework for C
3     Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams
4     [Released under MIT License. Please refer to license.txt for details]
5 ============================================================================ */
6 
7 #define UNITY_INCLUDE_SETUP_STUBS
8 #include "unity.h"
9 #include <stddef.h>
10 
11 /* If omitted from header, declare overrideable prototypes here so they're ready for use */
12 #ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION
13 void UNITY_OUTPUT_CHAR(int);
14 #endif
15 
16 /* Helpful macros for us to use here in Assert functions */
17 #define UNITY_FAIL_AND_BAIL   { Unity.CurrentTestFailed  = 1; TEST_ABORT(); }
18 #define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; TEST_ABORT(); }
19 #define RETURN_IF_FAIL_OR_IGNORE if (Unity.CurrentTestFailed || Unity.CurrentTestIgnored) return
20 
21 struct UNITY_STORAGE_T Unity;
22 
23 #ifdef UNITY_OUTPUT_COLOR
24 static const char UnityStrOk[]                     = "\033[42mOK\033[00m";
25 static const char UnityStrPass[]                   = "\033[42mPASS\033[00m";
26 static const char UnityStrFail[]                   = "\033[41mFAIL\033[00m";
27 static const char UnityStrIgnore[]                 = "\033[43mIGNORE\033[00m";
28 #else
29 static const char UnityStrOk[]                     = "OK";
30 static const char UnityStrPass[]                   = "PASS";
31 static const char UnityStrFail[]                   = "FAIL";
32 static const char UnityStrIgnore[]                 = "IGNORE";
33 #endif
34 static const char UnityStrNull[]                   = "NULL";
35 static const char UnityStrSpacer[]                 = ". ";
36 static const char UnityStrExpected[]               = " Expected ";
37 static const char UnityStrWas[]                    = " Was ";
38 static const char UnityStrGt[]                     = " to be greater than ";
39 static const char UnityStrLt[]                     = " to be less than ";
40 static const char UnityStrOrEqual[]                = "or equal to ";
41 static const char UnityStrElement[]                = " Element ";
42 static const char UnityStrByte[]                   = " Byte ";
43 static const char UnityStrMemory[]                 = " Memory Mismatch.";
44 static const char UnityStrDelta[]                  = " Values Not Within Delta ";
45 static const char UnityStrPointless[]              = " You Asked Me To Compare Nothing, Which Was Pointless.";
46 static const char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL";
47 static const char UnityStrNullPointerForActual[]   = " Actual pointer was NULL";
48 #ifndef UNITY_EXCLUDE_FLOAT
49 static const char UnityStrNot[]                    = "Not ";
50 static const char UnityStrInf[]                    = "Infinity";
51 static const char UnityStrNegInf[]                 = "Negative Infinity";
52 static const char UnityStrNaN[]                    = "NaN";
53 static const char UnityStrDet[]                    = "Determinate";
54 static const char UnityStrInvalidFloatTrait[]      = "Invalid Float Trait";
55 #endif
56 const char UnityStrErrFloat[]                      = "Unity Floating Point Disabled";
57 const char UnityStrErrDouble[]                     = "Unity Double Precision Disabled";
58 const char UnityStrErr64[]                         = "Unity 64-bit Support Disabled";
59 static const char UnityStrBreaker[]                = "-----------------------";
60 static const char UnityStrResultsTests[]           = " Tests ";
61 static const char UnityStrResultsFailures[]        = " Failures ";
62 static const char UnityStrResultsIgnored[]         = " Ignored ";
63 static const char UnityStrDetail1Name[]            = UNITY_DETAIL1_NAME " ";
64 static const char UnityStrDetail2Name[]            = " " UNITY_DETAIL2_NAME " ";
65 
66 /*-----------------------------------------------
67  * Pretty Printers & Test Result Output Handlers
68  *-----------------------------------------------*/
69 
UnityPrint(const char * string)70 void UnityPrint(const char* string)
71 {
72     const char* pch = string;
73 
74     if (pch != NULL)
75     {
76         while (*pch)
77         {
78             /* printable characters plus CR & LF are printed */
79             if ((*pch <= 126) && (*pch >= 32))
80             {
81                 UNITY_OUTPUT_CHAR(*pch);
82             }
83             /* write escaped carriage returns */
84             else if (*pch == 13)
85             {
86                 UNITY_OUTPUT_CHAR('\\');
87                 UNITY_OUTPUT_CHAR('r');
88             }
89             /* write escaped line feeds */
90             else if (*pch == 10)
91             {
92                 UNITY_OUTPUT_CHAR('\\');
93                 UNITY_OUTPUT_CHAR('n');
94             }
95 #ifdef UNITY_OUTPUT_COLOR
96             /* print ANSI escape code */
97             else if (*pch == 27 && *(pch + 1) == '[')
98             {
99                 while (*pch && *pch != 'm')
100                 {
101                     UNITY_OUTPUT_CHAR(*pch);
102                     pch++;
103                 }
104                 UNITY_OUTPUT_CHAR('m');
105             }
106 #endif
107             /* unprintable characters are shown as codes */
108             else
109             {
110                 UNITY_OUTPUT_CHAR('\\');
111                 UNITY_OUTPUT_CHAR('x');
112                 UnityPrintNumberHex((UNITY_UINT)*pch, 2);
113             }
114             pch++;
115         }
116     }
117 }
118 
UnityPrintLen(const char * string,const UNITY_UINT32 length)119 void UnityPrintLen(const char* string, const UNITY_UINT32 length)
120 {
121     const char* pch = string;
122 
123     if (pch != NULL)
124     {
125         while (*pch && (UNITY_UINT32)(pch - string) < length)
126         {
127             /* printable characters plus CR & LF are printed */
128             if ((*pch <= 126) && (*pch >= 32))
129             {
130                 UNITY_OUTPUT_CHAR(*pch);
131             }
132             /* write escaped carriage returns */
133             else if (*pch == 13)
134             {
135                 UNITY_OUTPUT_CHAR('\\');
136                 UNITY_OUTPUT_CHAR('r');
137             }
138             /* write escaped line feeds */
139             else if (*pch == 10)
140             {
141                 UNITY_OUTPUT_CHAR('\\');
142                 UNITY_OUTPUT_CHAR('n');
143             }
144             /* unprintable characters are shown as codes */
145             else
146             {
147                 UNITY_OUTPUT_CHAR('\\');
148                 UNITY_OUTPUT_CHAR('x');
149                 UnityPrintNumberHex((UNITY_UINT)*pch, 2);
150             }
151             pch++;
152         }
153     }
154 }
155 
156 /*-----------------------------------------------*/
UnityPrintNumberByStyle(const UNITY_INT number,const UNITY_DISPLAY_STYLE_T style)157 void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style)
158 {
159     if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
160     {
161         UnityPrintNumber(number);
162     }
163     else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT)
164     {
165         UnityPrintNumberUnsigned((UNITY_UINT)number);
166     }
167     else
168     {
169         UNITY_OUTPUT_CHAR('0');
170         UNITY_OUTPUT_CHAR('x');
171         UnityPrintNumberHex((UNITY_UINT)number, (char)((style & 0xF) * 2));
172     }
173 }
174 
175 /*-----------------------------------------------*/
UnityPrintNumber(const UNITY_INT number_to_print)176 void UnityPrintNumber(const UNITY_INT number_to_print)
177 {
178     UNITY_UINT number = (UNITY_UINT)number_to_print;
179 
180     if (number_to_print < 0)
181     {
182         /* A negative number, including MIN negative */
183         UNITY_OUTPUT_CHAR('-');
184         number = (UNITY_UINT)(-number_to_print);
185     }
186     UnityPrintNumberUnsigned(number);
187 }
188 
189 /*-----------------------------------------------
190  * basically do an itoa using as little ram as possible */
UnityPrintNumberUnsigned(const UNITY_UINT number)191 void UnityPrintNumberUnsigned(const UNITY_UINT number)
192 {
193     UNITY_UINT divisor = 1;
194 
195     /* figure out initial divisor */
196     while (number / divisor > 9)
197     {
198         divisor *= 10;
199     }
200 
201     /* now mod and print, then divide divisor */
202     do
203     {
204         UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
205         divisor /= 10;
206     } while (divisor > 0);
207 }
208 
209 /*-----------------------------------------------*/
UnityPrintNumberHex(const UNITY_UINT number,const char nibbles_to_print)210 void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print)
211 {
212     int nibble;
213     char nibbles = nibbles_to_print;
214     if ((unsigned)nibbles > (2 * sizeof(number)))
215         nibbles = 2 * sizeof(number);
216 
217     while (nibbles > 0)
218     {
219         nibbles--;
220         nibble = (int)(number >> (nibbles * 4)) & 0x0F;
221         if (nibble <= 9)
222         {
223             UNITY_OUTPUT_CHAR((char)('0' + nibble));
224         }
225         else
226         {
227             UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble));
228         }
229     }
230 }
231 
232 /*-----------------------------------------------*/
UnityPrintMask(const UNITY_UINT mask,const UNITY_UINT number)233 void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number)
234 {
235     UNITY_UINT current_bit = (UNITY_UINT)1 << (UNITY_INT_WIDTH - 1);
236     UNITY_INT32 i;
237 
238     for (i = 0; i < UNITY_INT_WIDTH; i++)
239     {
240         if (current_bit & mask)
241         {
242             if (current_bit & number)
243             {
244                 UNITY_OUTPUT_CHAR('1');
245             }
246             else
247             {
248                 UNITY_OUTPUT_CHAR('0');
249             }
250         }
251         else
252         {
253             UNITY_OUTPUT_CHAR('X');
254         }
255         current_bit = current_bit >> 1;
256     }
257 }
258 
259 /*-----------------------------------------------*/
260 #ifndef UNITY_EXCLUDE_FLOAT_PRINT
261 /* This function prints a floating-point value in a format similar to
262  * printf("%.6g").  It can work with either single- or double-precision,
263  * but for simplicity, it prints only 6 significant digits in either case.
264  * Printing more than 6 digits accurately is hard (at least in the single-
265  * precision case) and isn't attempted here. */
UnityPrintFloat(const UNITY_DOUBLE input_number)266 void UnityPrintFloat(const UNITY_DOUBLE input_number)
267 {
268     UNITY_DOUBLE number = input_number;
269 
270     /* print minus sign (including for negative zero) */
271     if (number < (double)0.0f || (number == (double)0.0f && (double)1.0f / number < (double)0.0f))
272     {
273         UNITY_OUTPUT_CHAR('-');
274         number = -number;
275     }
276 
277     /* handle zero, NaN, and +/- infinity */
278     if (number == (double)0.0f) UnityPrint("0");
279     else if (isnan(number)) UnityPrint("nan");
280     else if (isinf(number)) UnityPrint("inf");
281     else
282     {
283         int exponent = 0;
284         int decimals, digits;
285         UNITY_INT32 n;
286         char buf[16];
287 
288         /* scale up or down by powers of 10 */
289         while (number < (double)(100000.0f / 1e6f))  { number *= (double)1e6f; exponent -= 6; }
290         while (number < (double)100000.0f)         { number *= (double)10.0f; exponent--; }
291         while (number > (double)(1000000.0f * 1e6f)) { number /= (double)1e6f; exponent += 6; }
292         while (number > (double)1000000.0f)        { number /= (double)10.0f; exponent++; }
293 
294         /* round to nearest integer */
295         n = ((UNITY_INT32)(number + number) + 1) / 2;
296         if (n > 999999)
297         {
298             n = 100000;
299             exponent++;
300         }
301 
302         /* determine where to place decimal point */
303         decimals = (exponent <= 0 && exponent >= -9) ? -exponent : 5;
304         exponent += decimals;
305 
306         /* truncate trailing zeroes after decimal point */
307         while (decimals > 0 && n % 10 == 0)
308         {
309             n /= 10;
310             decimals--;
311         }
312 
313         /* build up buffer in reverse order */
314         digits = 0;
315         while (n != 0 || digits < decimals + 1)
316         {
317             buf[digits++] = (char)('0' + n % 10);
318             n /= 10;
319         }
320         while (digits > 0)
321         {
322             if(digits == decimals) UNITY_OUTPUT_CHAR('.');
323             UNITY_OUTPUT_CHAR(buf[--digits]);
324         }
325 
326         /* print exponent if needed */
327         if (exponent != 0)
328         {
329             UNITY_OUTPUT_CHAR('e');
330 
331             if(exponent < 0)
332             {
333                 UNITY_OUTPUT_CHAR('-');
334                 exponent = -exponent;
335             }
336             else
337             {
338                 UNITY_OUTPUT_CHAR('+');
339             }
340 
341             digits = 0;
342             while (exponent != 0 || digits < 2)
343             {
344                 buf[digits++] = (char)('0' + exponent % 10);
345                 exponent /= 10;
346             }
347             while (digits > 0)
348             {
349                 UNITY_OUTPUT_CHAR(buf[--digits]);
350             }
351         }
352     }
353 }
354 #endif /* ! UNITY_EXCLUDE_FLOAT_PRINT */
355 
356 /*-----------------------------------------------*/
UnityTestResultsBegin(const char * file,const UNITY_LINE_TYPE line)357 static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line)
358 {
359     UnityPrint(file);
360     UNITY_OUTPUT_CHAR(':');
361     UnityPrintNumber((UNITY_INT)line);
362     UNITY_OUTPUT_CHAR(':');
363     UnityPrint(Unity.CurrentTestName);
364     UNITY_OUTPUT_CHAR(':');
365 }
366 
367 /*-----------------------------------------------*/
UnityTestResultsFailBegin(const UNITY_LINE_TYPE line)368 static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line)
369 {
370     UnityTestResultsBegin(Unity.TestFile, line);
371     UnityPrint(UnityStrFail);
372     UNITY_OUTPUT_CHAR(':');
373 }
374 
375 /*-----------------------------------------------*/
UnityConcludeTest(void)376 void UnityConcludeTest(void)
377 {
378     if (Unity.CurrentTestIgnored)
379     {
380         Unity.TestIgnores++;
381     }
382     else if (!Unity.CurrentTestFailed)
383     {
384         UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber);
385         UnityPrint(UnityStrPass);
386     }
387     else
388     {
389         Unity.TestFailures++;
390     }
391 
392     Unity.CurrentTestFailed = 0;
393     Unity.CurrentTestIgnored = 0;
394     UNITY_PRINT_EOL();
395     UNITY_FLUSH_CALL();
396 }
397 
398 /*-----------------------------------------------*/
UnityAddMsgIfSpecified(const char * msg)399 static void UnityAddMsgIfSpecified(const char* msg)
400 {
401     if (msg)
402     {
403         UnityPrint(UnityStrSpacer);
404 #ifndef UNITY_EXCLUDE_DETAILS
405         if (Unity.CurrentDetail1)
406         {
407             UnityPrint(UnityStrDetail1Name);
408             UnityPrint(Unity.CurrentDetail1);
409             if (Unity.CurrentDetail2)
410             {
411                 UnityPrint(UnityStrDetail2Name);
412                 UnityPrint(Unity.CurrentDetail2);
413             }
414             UnityPrint(UnityStrSpacer);
415         }
416 #endif
417         UnityPrint(msg);
418     }
419 }
420 
421 /*-----------------------------------------------*/
UnityPrintExpectedAndActualStrings(const char * expected,const char * actual)422 static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual)
423 {
424     UnityPrint(UnityStrExpected);
425     if (expected != NULL)
426     {
427         UNITY_OUTPUT_CHAR('\'');
428         UnityPrint(expected);
429         UNITY_OUTPUT_CHAR('\'');
430     }
431     else
432     {
433         UnityPrint(UnityStrNull);
434     }
435     UnityPrint(UnityStrWas);
436     if (actual != NULL)
437     {
438         UNITY_OUTPUT_CHAR('\'');
439         UnityPrint(actual);
440         UNITY_OUTPUT_CHAR('\'');
441     }
442     else
443     {
444         UnityPrint(UnityStrNull);
445     }
446 }
447 
448 /*-----------------------------------------------*/
UnityPrintExpectedAndActualStringsLen(const char * expected,const char * actual,const UNITY_UINT32 length)449 static void UnityPrintExpectedAndActualStringsLen(const char* expected,
450                                                   const char* actual,
451                                                   const UNITY_UINT32 length)
452 {
453     UnityPrint(UnityStrExpected);
454     if (expected != NULL)
455     {
456         UNITY_OUTPUT_CHAR('\'');
457         UnityPrintLen(expected, length);
458         UNITY_OUTPUT_CHAR('\'');
459     }
460     else
461     {
462         UnityPrint(UnityStrNull);
463     }
464     UnityPrint(UnityStrWas);
465     if (actual != NULL)
466     {
467         UNITY_OUTPUT_CHAR('\'');
468         UnityPrintLen(actual, length);
469         UNITY_OUTPUT_CHAR('\'');
470     }
471     else
472     {
473         UnityPrint(UnityStrNull);
474     }
475 }
476 
477 /*-----------------------------------------------
478  * Assertion & Control Helpers
479  *-----------------------------------------------*/
480 
UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected,UNITY_INTERNAL_PTR actual,const UNITY_LINE_TYPE lineNumber,const char * msg)481 static int UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected,
482                                UNITY_INTERNAL_PTR actual,
483                                const UNITY_LINE_TYPE lineNumber,
484                                const char* msg)
485 {
486     if (expected == actual) return 0; /* Both are NULL or same pointer */
487 
488     /* print and return true if just expected is NULL */
489     if (expected == NULL)
490     {
491         UnityTestResultsFailBegin(lineNumber);
492         UnityPrint(UnityStrNullPointerForExpected);
493         UnityAddMsgIfSpecified(msg);
494         return 1;
495     }
496 
497     /* print and return true if just actual is NULL */
498     if (actual == NULL)
499     {
500         UnityTestResultsFailBegin(lineNumber);
501         UnityPrint(UnityStrNullPointerForActual);
502         UnityAddMsgIfSpecified(msg);
503         return 1;
504     }
505 
506     return 0; /* return false if neither is NULL */
507 }
508 
509 /*-----------------------------------------------
510  * Assertion Functions
511  *-----------------------------------------------*/
512 
UnityAssertBits(const UNITY_INT mask,const UNITY_INT expected,const UNITY_INT actual,const char * msg,const UNITY_LINE_TYPE lineNumber)513 void UnityAssertBits(const UNITY_INT mask,
514                      const UNITY_INT expected,
515                      const UNITY_INT actual,
516                      const char* msg,
517                      const UNITY_LINE_TYPE lineNumber)
518 {
519     RETURN_IF_FAIL_OR_IGNORE;
520 
521     if ((mask & expected) != (mask & actual))
522     {
523         UnityTestResultsFailBegin(lineNumber);
524         UnityPrint(UnityStrExpected);
525         UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)expected);
526         UnityPrint(UnityStrWas);
527         UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)actual);
528         UnityAddMsgIfSpecified(msg);
529         UNITY_FAIL_AND_BAIL;
530     }
531 }
532 
533 /*-----------------------------------------------*/
UnityAssertEqualNumber(const UNITY_INT expected,const UNITY_INT actual,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_DISPLAY_STYLE_T style)534 void UnityAssertEqualNumber(const UNITY_INT expected,
535                             const UNITY_INT actual,
536                             const char* msg,
537                             const UNITY_LINE_TYPE lineNumber,
538                             const UNITY_DISPLAY_STYLE_T style)
539 {
540     RETURN_IF_FAIL_OR_IGNORE;
541 
542     if (expected != actual)
543     {
544         UnityTestResultsFailBegin(lineNumber);
545         UnityPrint(UnityStrExpected);
546         UnityPrintNumberByStyle(expected, style);
547         UnityPrint(UnityStrWas);
548         UnityPrintNumberByStyle(actual, style);
549         UnityAddMsgIfSpecified(msg);
550         UNITY_FAIL_AND_BAIL;
551     }
552 }
553 
554 /*-----------------------------------------------*/
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)555 void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold,
556                                            const UNITY_INT actual,
557                                            const UNITY_COMPARISON_T compare,
558                                            const char *msg,
559                                            const UNITY_LINE_TYPE lineNumber,
560                                            const UNITY_DISPLAY_STYLE_T style)
561 {
562     int failed = 0;
563     RETURN_IF_FAIL_OR_IGNORE;
564 
565     if (threshold == actual && compare & UNITY_EQUAL_TO) return;
566     if (threshold == actual) failed = 1;
567 
568     if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
569     {
570         if (actual > threshold && compare & UNITY_SMALLER_THAN) failed = 1;
571         if (actual < threshold && compare & UNITY_GREATER_THAN) failed = 1;
572     }
573     else /* UINT or HEX */
574     {
575         if ((UNITY_UINT)actual > (UNITY_UINT)threshold && compare & UNITY_SMALLER_THAN) failed = 1;
576         if ((UNITY_UINT)actual < (UNITY_UINT)threshold && compare & UNITY_GREATER_THAN) failed = 1;
577     }
578 
579     if (failed)
580     {
581         UnityTestResultsFailBegin(lineNumber);
582         UnityPrint(UnityStrExpected);
583         UnityPrintNumberByStyle(actual, style);
584         if (compare & UNITY_GREATER_THAN) UnityPrint(UnityStrGt);
585         if (compare & UNITY_SMALLER_THAN) UnityPrint(UnityStrLt);
586         if (compare & UNITY_EQUAL_TO)     UnityPrint(UnityStrOrEqual);
587         UnityPrintNumberByStyle(threshold, style);
588         UnityAddMsgIfSpecified(msg);
589         UNITY_FAIL_AND_BAIL;
590     }
591 }
592 
593 #define UnityPrintPointlessAndBail()       \
594 {                                          \
595     UnityTestResultsFailBegin(lineNumber); \
596     UnityPrint(UnityStrPointless);         \
597     UnityAddMsgIfSpecified(msg);           \
598     UNITY_FAIL_AND_BAIL; }
599 
600 /*-----------------------------------------------*/
UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,UNITY_INTERNAL_PTR actual,const UNITY_UINT32 num_elements,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_DISPLAY_STYLE_T style,const UNITY_FLAGS_T flags)601 void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
602                               UNITY_INTERNAL_PTR actual,
603                               const UNITY_UINT32 num_elements,
604                               const char* msg,
605                               const UNITY_LINE_TYPE lineNumber,
606                               const UNITY_DISPLAY_STYLE_T style,
607                               const UNITY_FLAGS_T flags)
608 {
609     UNITY_UINT32 elements = num_elements;
610     unsigned int length   = style & 0xF;
611 
612     RETURN_IF_FAIL_OR_IGNORE;
613 
614     if (num_elements == 0)
615     {
616         UnityPrintPointlessAndBail();
617     }
618 
619     if (expected == actual) return; /* Both are NULL or same pointer */
620     if (UnityIsOneArrayNull(expected, actual, lineNumber, msg))
621         UNITY_FAIL_AND_BAIL;
622 
623     while (elements--)
624     {
625         UNITY_INT expect_val;
626         UNITY_INT actual_val;
627         switch (length)
628         {
629             case 1:
630                 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected;
631                 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual;
632                 break;
633             case 2:
634                 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected;
635                 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual;
636                 break;
637 #ifdef UNITY_SUPPORT_64
638             case 8:
639                 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected;
640                 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual;
641                 break;
642 #endif
643             default: /* length 4 bytes */
644                 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected;
645                 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual;
646                 length = 4;
647                 break;
648         }
649 
650         if (expect_val != actual_val)
651         {
652             if (style & UNITY_DISPLAY_RANGE_UINT && length < sizeof(expect_val))
653             {   /* For UINT, remove sign extension (padding 1's) from signed type casts above */
654                 UNITY_INT mask = 1;
655                 mask = (mask << 8 * length) - 1;
656                 expect_val &= mask;
657                 actual_val &= mask;
658             }
659             UnityTestResultsFailBegin(lineNumber);
660             UnityPrint(UnityStrElement);
661             UnityPrintNumberUnsigned(num_elements - elements - 1);
662             UnityPrint(UnityStrExpected);
663             UnityPrintNumberByStyle(expect_val, style);
664             UnityPrint(UnityStrWas);
665             UnityPrintNumberByStyle(actual_val, style);
666             UnityAddMsgIfSpecified(msg);
667             UNITY_FAIL_AND_BAIL;
668         }
669         if (flags == UNITY_ARRAY_TO_ARRAY)
670         {
671             expected = (UNITY_INTERNAL_PTR)(length + (const char*)expected);
672         }
673         actual   = (UNITY_INTERNAL_PTR)(length + (const char*)actual);
674     }
675 }
676 
677 /*-----------------------------------------------*/
678 #ifndef UNITY_EXCLUDE_FLOAT
679 /* Wrap this define in a function with variable types as float or double */
680 #define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff)                       \
681     if (isinf(expected) && isinf(actual) && ((expected < 0) == (actual < 0))) return 1;   \
682     if (UNITY_NAN_CHECK) return 1;                                                        \
683     diff = actual - expected;                                                             \
684     if (diff < 0) diff = -diff;                                                           \
685     if (delta < 0) delta = -delta;                                                        \
686     return !(isnan(diff) || isinf(diff) || (diff > delta))
687     /* This first part of this condition will catch any NaN or Infinite values */
688 #ifndef UNITY_NAN_NOT_EQUAL_NAN
689   #define UNITY_NAN_CHECK isnan(expected) && isnan(actual)
690 #else
691   #define UNITY_NAN_CHECK 0
692 #endif
693 
694 #ifndef UNITY_EXCLUDE_FLOAT_PRINT
695   #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \
696   {                                                               \
697     UnityPrint(UnityStrExpected);                                 \
698     UnityPrintFloat(expected);                                    \
699     UnityPrint(UnityStrWas);                                      \
700     UnityPrintFloat(actual); }
701 #else
702   #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \
703     UnityPrint(UnityStrDelta)
704 #endif /* UNITY_EXCLUDE_FLOAT_PRINT */
705 
UnityFloatsWithin(UNITY_FLOAT delta,UNITY_FLOAT expected,UNITY_FLOAT actual)706 static int UnityFloatsWithin(UNITY_FLOAT delta, UNITY_FLOAT expected, UNITY_FLOAT actual)
707 {
708     UNITY_FLOAT diff;
709     UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff);
710 }
711 
UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT * expected,UNITY_PTR_ATTRIBUTE const UNITY_FLOAT * actual,const UNITY_UINT32 num_elements,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLAGS_T flags)712 void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected,
713                                 UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual,
714                                 const UNITY_UINT32 num_elements,
715                                 const char* msg,
716                                 const UNITY_LINE_TYPE lineNumber,
717                                 const UNITY_FLAGS_T flags)
718 {
719     UNITY_UINT32 elements = num_elements;
720     UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_expected = expected;
721     UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_actual = actual;
722 
723     RETURN_IF_FAIL_OR_IGNORE;
724 
725     if (elements == 0)
726     {
727         UnityPrintPointlessAndBail();
728     }
729 
730     if (expected == actual) return; /* Both are NULL or same pointer */
731     if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
732         UNITY_FAIL_AND_BAIL;
733 
734     while (elements--)
735     {
736         if (!UnityFloatsWithin(*ptr_expected * UNITY_FLOAT_PRECISION, *ptr_expected, *ptr_actual))
737         {
738             UnityTestResultsFailBegin(lineNumber);
739             UnityPrint(UnityStrElement);
740             UnityPrintNumberUnsigned(num_elements - elements - 1);
741             UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)*ptr_expected, (UNITY_DOUBLE)*ptr_actual);
742             UnityAddMsgIfSpecified(msg);
743             UNITY_FAIL_AND_BAIL;
744         }
745         if (flags == UNITY_ARRAY_TO_ARRAY)
746         {
747             ptr_expected++;
748         }
749         ptr_actual++;
750     }
751 }
752 
753 /*-----------------------------------------------*/
UnityAssertFloatsWithin(const UNITY_FLOAT delta,const UNITY_FLOAT expected,const UNITY_FLOAT actual,const char * msg,const UNITY_LINE_TYPE lineNumber)754 void UnityAssertFloatsWithin(const UNITY_FLOAT delta,
755                              const UNITY_FLOAT expected,
756                              const UNITY_FLOAT actual,
757                              const char* msg,
758                              const UNITY_LINE_TYPE lineNumber)
759 {
760     RETURN_IF_FAIL_OR_IGNORE;
761 
762 
763     if (!UnityFloatsWithin(delta, expected, actual))
764     {
765         UnityTestResultsFailBegin(lineNumber);
766         UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual);
767         UnityAddMsgIfSpecified(msg);
768         UNITY_FAIL_AND_BAIL;
769     }
770 }
771 
772 /*-----------------------------------------------*/
UnityAssertFloatSpecial(const UNITY_FLOAT actual,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLOAT_TRAIT_T style)773 void UnityAssertFloatSpecial(const UNITY_FLOAT actual,
774                              const char* msg,
775                              const UNITY_LINE_TYPE lineNumber,
776                              const UNITY_FLOAT_TRAIT_T style)
777 {
778     const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet};
779     UNITY_INT should_be_trait = ((UNITY_INT)style & 1);
780     UNITY_INT is_trait        = !should_be_trait;
781     UNITY_INT trait_index     = (UNITY_INT)(style >> 1);
782 
783     RETURN_IF_FAIL_OR_IGNORE;
784 
785     switch (style)
786     {
787         case UNITY_FLOAT_IS_INF:
788         case UNITY_FLOAT_IS_NOT_INF:
789             is_trait = isinf(actual) && (actual > 0);
790             break;
791         case UNITY_FLOAT_IS_NEG_INF:
792         case UNITY_FLOAT_IS_NOT_NEG_INF:
793             is_trait = isinf(actual) && (actual < 0);
794             break;
795 
796         case UNITY_FLOAT_IS_NAN:
797         case UNITY_FLOAT_IS_NOT_NAN:
798             is_trait = isnan(actual) ? 1 : 0;
799             break;
800 
801         case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */
802         case UNITY_FLOAT_IS_NOT_DET:
803             is_trait = !isinf(actual) && !isnan(actual);
804             break;
805 
806         default:
807             trait_index = 0;
808             trait_names[0] = UnityStrInvalidFloatTrait;
809             break;
810     }
811 
812     if (is_trait != should_be_trait)
813     {
814         UnityTestResultsFailBegin(lineNumber);
815         UnityPrint(UnityStrExpected);
816         if (!should_be_trait)
817             UnityPrint(UnityStrNot);
818         UnityPrint(trait_names[trait_index]);
819         UnityPrint(UnityStrWas);
820 #ifndef UNITY_EXCLUDE_FLOAT_PRINT
821         UnityPrintFloat((UNITY_DOUBLE)actual);
822 #else
823         if (should_be_trait)
824             UnityPrint(UnityStrNot);
825         UnityPrint(trait_names[trait_index]);
826 #endif
827         UnityAddMsgIfSpecified(msg);
828         UNITY_FAIL_AND_BAIL;
829     }
830 }
831 
832 #endif /* not UNITY_EXCLUDE_FLOAT */
833 
834 /*-----------------------------------------------*/
835 #ifndef UNITY_EXCLUDE_DOUBLE
UnityDoublesWithin(UNITY_DOUBLE delta,UNITY_DOUBLE expected,UNITY_DOUBLE actual)836 static int UnityDoublesWithin(UNITY_DOUBLE delta, UNITY_DOUBLE expected, UNITY_DOUBLE actual)
837 {
838     UNITY_DOUBLE diff;
839     UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff);
840 }
841 
UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE * expected,UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE * actual,const UNITY_UINT32 num_elements,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLAGS_T flags)842 void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected,
843                                  UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual,
844                                  const UNITY_UINT32 num_elements,
845                                  const char* msg,
846                                  const UNITY_LINE_TYPE lineNumber,
847                                  const UNITY_FLAGS_T flags)
848 {
849     UNITY_UINT32 elements = num_elements;
850     UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_expected = expected;
851     UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_actual = actual;
852 
853     RETURN_IF_FAIL_OR_IGNORE;
854 
855     if (elements == 0)
856     {
857         UnityPrintPointlessAndBail();
858     }
859 
860     if (expected == actual) return; /* Both are NULL or same pointer */
861     if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
862         UNITY_FAIL_AND_BAIL;
863 
864     while (elements--)
865     {
866         if (!UnityDoublesWithin(*ptr_expected * UNITY_DOUBLE_PRECISION, *ptr_expected, *ptr_actual))
867         {
868             UnityTestResultsFailBegin(lineNumber);
869             UnityPrint(UnityStrElement);
870             UnityPrintNumberUnsigned(num_elements - elements - 1);
871             UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(*ptr_expected, *ptr_actual);
872             UnityAddMsgIfSpecified(msg);
873             UNITY_FAIL_AND_BAIL;
874         }
875         if (flags == UNITY_ARRAY_TO_ARRAY)
876         {
877             ptr_expected++;
878         }
879         ptr_actual++;
880     }
881 }
882 
883 /*-----------------------------------------------*/
UnityAssertDoublesWithin(const UNITY_DOUBLE delta,const UNITY_DOUBLE expected,const UNITY_DOUBLE actual,const char * msg,const UNITY_LINE_TYPE lineNumber)884 void UnityAssertDoublesWithin(const UNITY_DOUBLE delta,
885                               const UNITY_DOUBLE expected,
886                               const UNITY_DOUBLE actual,
887                               const char* msg,
888                               const UNITY_LINE_TYPE lineNumber)
889 {
890     RETURN_IF_FAIL_OR_IGNORE;
891 
892     if (!UnityDoublesWithin(delta, expected, actual))
893     {
894         UnityTestResultsFailBegin(lineNumber);
895         UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual);
896         UnityAddMsgIfSpecified(msg);
897         UNITY_FAIL_AND_BAIL;
898     }
899 }
900 
901 /*-----------------------------------------------*/
902 
UnityAssertDoubleSpecial(const UNITY_DOUBLE actual,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLOAT_TRAIT_T style)903 void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual,
904                               const char* msg,
905                               const UNITY_LINE_TYPE lineNumber,
906                               const UNITY_FLOAT_TRAIT_T style)
907 {
908     const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet};
909     UNITY_INT should_be_trait = ((UNITY_INT)style & 1);
910     UNITY_INT is_trait        = !should_be_trait;
911     UNITY_INT trait_index     = (UNITY_INT)(style >> 1);
912 
913     RETURN_IF_FAIL_OR_IGNORE;
914 
915     switch (style)
916     {
917         case UNITY_FLOAT_IS_INF:
918         case UNITY_FLOAT_IS_NOT_INF:
919             is_trait = isinf(actual) && (actual > 0);
920             break;
921         case UNITY_FLOAT_IS_NEG_INF:
922         case UNITY_FLOAT_IS_NOT_NEG_INF:
923             is_trait = isinf(actual) && (actual < 0);
924             break;
925 
926         case UNITY_FLOAT_IS_NAN:
927         case UNITY_FLOAT_IS_NOT_NAN:
928             is_trait = isnan(actual) ? 1 : 0;
929             break;
930 
931         case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */
932         case UNITY_FLOAT_IS_NOT_DET:
933             is_trait = !isinf(actual) && !isnan(actual);
934             break;
935 
936         default:
937             trait_index = 0;
938             trait_names[0] = UnityStrInvalidFloatTrait;
939             break;
940     }
941 
942     if (is_trait != should_be_trait)
943     {
944         UnityTestResultsFailBegin(lineNumber);
945         UnityPrint(UnityStrExpected);
946         if (!should_be_trait)
947             UnityPrint(UnityStrNot);
948         UnityPrint(trait_names[trait_index]);
949         UnityPrint(UnityStrWas);
950 #ifndef UNITY_EXCLUDE_FLOAT_PRINT
951         UnityPrintFloat(actual);
952 #else
953         if (should_be_trait)
954             UnityPrint(UnityStrNot);
955         UnityPrint(trait_names[trait_index]);
956 #endif
957         UnityAddMsgIfSpecified(msg);
958         UNITY_FAIL_AND_BAIL;
959     }
960 }
961 
962 #endif /* not UNITY_EXCLUDE_DOUBLE */
963 
964 /*-----------------------------------------------*/
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)965 void UnityAssertNumbersWithin(const UNITY_UINT delta,
966                               const UNITY_INT expected,
967                               const UNITY_INT actual,
968                               const char* msg,
969                               const UNITY_LINE_TYPE lineNumber,
970                               const UNITY_DISPLAY_STYLE_T style)
971 {
972     RETURN_IF_FAIL_OR_IGNORE;
973 
974     if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
975     {
976         if (actual > expected)
977           Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(actual - expected) > delta);
978         else
979             Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(expected - actual) > delta);
980     }
981     else
982     {
983         if ((UNITY_UINT)actual > (UNITY_UINT)expected)
984             Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(actual - expected) > delta);
985         else
986             Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(expected - actual) > delta);
987     }
988 
989     if (Unity.CurrentTestFailed)
990     {
991         UnityTestResultsFailBegin(lineNumber);
992         UnityPrint(UnityStrDelta);
993         UnityPrintNumberByStyle((UNITY_INT)delta, style);
994         UnityPrint(UnityStrExpected);
995         UnityPrintNumberByStyle(expected, style);
996         UnityPrint(UnityStrWas);
997         UnityPrintNumberByStyle(actual, style);
998         UnityAddMsgIfSpecified(msg);
999         UNITY_FAIL_AND_BAIL;
1000     }
1001 }
1002 
1003 /*-----------------------------------------------*/
UnityAssertEqualString(const char * expected,const char * actual,const char * msg,const UNITY_LINE_TYPE lineNumber)1004 void UnityAssertEqualString(const char* expected,
1005                             const char* actual,
1006                             const char* msg,
1007                             const UNITY_LINE_TYPE lineNumber)
1008 {
1009     UNITY_UINT32 i;
1010 
1011     RETURN_IF_FAIL_OR_IGNORE;
1012 
1013     /* if both pointers not null compare the strings */
1014     if (expected && actual)
1015     {
1016         for (i = 0; expected[i] || actual[i]; i++)
1017         {
1018             if (expected[i] != actual[i])
1019             {
1020                 Unity.CurrentTestFailed = 1;
1021                 break;
1022             }
1023         }
1024     }
1025     else
1026     { /* handle case of one pointers being null (if both null, test should pass) */
1027         if (expected != actual)
1028         {
1029             Unity.CurrentTestFailed = 1;
1030         }
1031     }
1032 
1033     if (Unity.CurrentTestFailed)
1034     {
1035         UnityTestResultsFailBegin(lineNumber);
1036         UnityPrintExpectedAndActualStrings(expected, actual);
1037         UnityAddMsgIfSpecified(msg);
1038         UNITY_FAIL_AND_BAIL;
1039     }
1040 }
1041 
1042 /*-----------------------------------------------*/
UnityAssertEqualStringLen(const char * expected,const char * actual,const UNITY_UINT32 length,const char * msg,const UNITY_LINE_TYPE lineNumber)1043 void UnityAssertEqualStringLen(const char* expected,
1044                                const char* actual,
1045                                const UNITY_UINT32 length,
1046                                const char* msg,
1047                                const UNITY_LINE_TYPE lineNumber)
1048 {
1049     UNITY_UINT32 i;
1050 
1051     RETURN_IF_FAIL_OR_IGNORE;
1052 
1053     /* if both pointers not null compare the strings */
1054     if (expected && actual)
1055     {
1056         for (i = 0; (i < length) && (expected[i] || actual[i]); i++)
1057         {
1058             if (expected[i] != actual[i])
1059             {
1060                 Unity.CurrentTestFailed = 1;
1061                 break;
1062             }
1063         }
1064     }
1065     else
1066     { /* handle case of one pointers being null (if both null, test should pass) */
1067         if (expected != actual)
1068         {
1069             Unity.CurrentTestFailed = 1;
1070         }
1071     }
1072 
1073     if (Unity.CurrentTestFailed)
1074     {
1075         UnityTestResultsFailBegin(lineNumber);
1076         UnityPrintExpectedAndActualStringsLen(expected, actual, length);
1077         UnityAddMsgIfSpecified(msg);
1078         UNITY_FAIL_AND_BAIL;
1079     }
1080 }
1081 
1082 /*-----------------------------------------------*/
UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,const char ** actual,const UNITY_UINT32 num_elements,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLAGS_T flags)1083 void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
1084                                  const char** actual,
1085                                  const UNITY_UINT32 num_elements,
1086                                  const char* msg,
1087                                  const UNITY_LINE_TYPE lineNumber,
1088                                  const UNITY_FLAGS_T flags)
1089 {
1090     UNITY_UINT32 i = 0;
1091     UNITY_UINT32 j = 0;
1092     const char* expd = NULL;
1093     const char* act = NULL;
1094 
1095     RETURN_IF_FAIL_OR_IGNORE;
1096 
1097     /* if no elements, it's an error */
1098     if (num_elements == 0)
1099     {
1100         UnityPrintPointlessAndBail();
1101     }
1102 
1103     if ((const void*)expected == (const void*)actual)
1104     {
1105         return; /* Both are NULL or same pointer */
1106     }
1107 
1108     if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
1109     {
1110         UNITY_FAIL_AND_BAIL;
1111     }
1112 
1113     if (flags != UNITY_ARRAY_TO_ARRAY)
1114     {
1115         expd = (const char*)expected;
1116     }
1117 
1118     do
1119     {
1120         act = actual[j];
1121         if (flags == UNITY_ARRAY_TO_ARRAY)
1122         {
1123             expd = ((const char* const*)expected)[j];
1124         }
1125 
1126         /* if both pointers not null compare the strings */
1127         if (expd && act)
1128         {
1129             for (i = 0; expd[i] || act[i]; i++)
1130             {
1131                 if (expd[i] != act[i])
1132                 {
1133                     Unity.CurrentTestFailed = 1;
1134                     break;
1135                 }
1136             }
1137         }
1138         else
1139         { /* handle case of one pointers being null (if both null, test should pass) */
1140             if (expd != act)
1141             {
1142                 Unity.CurrentTestFailed = 1;
1143             }
1144         }
1145 
1146         if (Unity.CurrentTestFailed)
1147         {
1148             UnityTestResultsFailBegin(lineNumber);
1149             if (num_elements > 1)
1150             {
1151                 UnityPrint(UnityStrElement);
1152                 UnityPrintNumberUnsigned(j);
1153             }
1154             UnityPrintExpectedAndActualStrings(expd, act);
1155             UnityAddMsgIfSpecified(msg);
1156             UNITY_FAIL_AND_BAIL;
1157         }
1158     } while (++j < num_elements);
1159 }
1160 
1161 /*-----------------------------------------------*/
UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected,UNITY_INTERNAL_PTR actual,const UNITY_UINT32 length,const UNITY_UINT32 num_elements,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLAGS_T flags)1162 void UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected,
1163                             UNITY_INTERNAL_PTR actual,
1164                             const UNITY_UINT32 length,
1165                             const UNITY_UINT32 num_elements,
1166                             const char* msg,
1167                             const UNITY_LINE_TYPE lineNumber,
1168                             const UNITY_FLAGS_T flags)
1169 {
1170     UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected;
1171     UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual;
1172     UNITY_UINT32 elements = num_elements;
1173     UNITY_UINT32 bytes;
1174 
1175     RETURN_IF_FAIL_OR_IGNORE;
1176 
1177     if ((elements == 0) || (length == 0))
1178     {
1179         UnityPrintPointlessAndBail();
1180     }
1181 
1182     if (expected == actual) return; /* Both are NULL or same pointer */
1183     if (UnityIsOneArrayNull(expected, actual, lineNumber, msg))
1184         UNITY_FAIL_AND_BAIL;
1185 
1186     while (elements--)
1187     {
1188         bytes = length;
1189         while (bytes--)
1190         {
1191             if (*ptr_exp != *ptr_act)
1192             {
1193                 UnityTestResultsFailBegin(lineNumber);
1194                 UnityPrint(UnityStrMemory);
1195                 if (num_elements > 1)
1196                 {
1197                     UnityPrint(UnityStrElement);
1198                     UnityPrintNumberUnsigned(num_elements - elements - 1);
1199                 }
1200                 UnityPrint(UnityStrByte);
1201                 UnityPrintNumberUnsigned(length - bytes - 1);
1202                 UnityPrint(UnityStrExpected);
1203                 UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8);
1204                 UnityPrint(UnityStrWas);
1205                 UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8);
1206                 UnityAddMsgIfSpecified(msg);
1207                 UNITY_FAIL_AND_BAIL;
1208             }
1209             ptr_exp++;
1210             ptr_act++;
1211         }
1212         if (flags == UNITY_ARRAY_TO_VAL)
1213         {
1214             ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected;
1215         }
1216     }
1217 }
1218 
1219 /*-----------------------------------------------*/
1220 
1221 static union
1222 {
1223     UNITY_INT8 i8;
1224     UNITY_INT16 i16;
1225     UNITY_INT32 i32;
1226 #ifdef UNITY_SUPPORT_64
1227     UNITY_INT64 i64;
1228 #endif
1229 #ifndef UNITY_EXCLUDE_FLOAT
1230     float f;
1231 #endif
1232 #ifndef UNITY_EXCLUDE_DOUBLE
1233     double d;
1234 #endif
1235 } UnityQuickCompare;
1236 
UnityNumToPtr(const UNITY_INT num,const UNITY_UINT8 size)1237 UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size)
1238 {
1239     switch(size)
1240     {
1241         case 1:
1242           UnityQuickCompare.i8 = (UNITY_INT8)num;
1243           return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i8);
1244 
1245         case 2:
1246           UnityQuickCompare.i16 = (UNITY_INT16)num;
1247           return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i16);
1248 
1249 #ifdef UNITY_SUPPORT_64
1250         case 8:
1251           UnityQuickCompare.i64 = (UNITY_INT64)num;
1252           return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i64);
1253 #endif
1254         default: /* 4 bytes */
1255           UnityQuickCompare.i32 = (UNITY_INT32)num;
1256           return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i32);
1257     }
1258 }
1259 
1260 #ifndef UNITY_EXCLUDE_FLOAT
UnityFloatToPtr(const float num)1261 UNITY_INTERNAL_PTR UnityFloatToPtr(const float num)
1262 {
1263     UnityQuickCompare.f = num;
1264     return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.f);
1265 }
1266 #endif
1267 
1268 #ifndef UNITY_EXCLUDE_DOUBLE
UnityDoubleToPtr(const double num)1269 UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num)
1270 {
1271     UnityQuickCompare.d = num;
1272     return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.d);
1273 }
1274 #endif
1275 
1276 /*-----------------------------------------------
1277  * Control Functions
1278  *-----------------------------------------------*/
1279 
UnityFail(const char * msg,const UNITY_LINE_TYPE line)1280 void UnityFail(const char* msg, const UNITY_LINE_TYPE line)
1281 {
1282     RETURN_IF_FAIL_OR_IGNORE;
1283 
1284     UnityTestResultsBegin(Unity.TestFile, line);
1285     UnityPrint(UnityStrFail);
1286     if (msg != NULL)
1287     {
1288         UNITY_OUTPUT_CHAR(':');
1289 
1290 #ifndef UNITY_EXCLUDE_DETAILS
1291         if (Unity.CurrentDetail1)
1292         {
1293             UnityPrint(UnityStrDetail1Name);
1294             UnityPrint(Unity.CurrentDetail1);
1295             if (Unity.CurrentDetail2)
1296             {
1297                 UnityPrint(UnityStrDetail2Name);
1298                 UnityPrint(Unity.CurrentDetail2);
1299             }
1300             UnityPrint(UnityStrSpacer);
1301         }
1302 #endif
1303         if (msg[0] != ' ')
1304         {
1305             UNITY_OUTPUT_CHAR(' ');
1306         }
1307         UnityPrint(msg);
1308     }
1309 
1310     UNITY_FAIL_AND_BAIL;
1311 }
1312 
1313 /*-----------------------------------------------*/
UnityIgnore(const char * msg,const UNITY_LINE_TYPE line)1314 void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line)
1315 {
1316     RETURN_IF_FAIL_OR_IGNORE;
1317 
1318     UnityTestResultsBegin(Unity.TestFile, line);
1319     UnityPrint(UnityStrIgnore);
1320     if (msg != NULL)
1321     {
1322         UNITY_OUTPUT_CHAR(':');
1323         UNITY_OUTPUT_CHAR(' ');
1324         UnityPrint(msg);
1325     }
1326     UNITY_IGNORE_AND_BAIL;
1327 }
1328 
1329 /*-----------------------------------------------*/
UnityDefaultTestRun(UnityTestFunction Func,const char * FuncName,const int FuncLineNum)1330 void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum)
1331 {
1332     Unity.CurrentTestName = FuncName;
1333     Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum;
1334     Unity.NumberOfTests++;
1335     UNITY_CLR_DETAILS();
1336     if (TEST_PROTECT())
1337     {
1338         setUp();
1339         Func();
1340     }
1341     if (TEST_PROTECT())
1342     {
1343         tearDown();
1344     }
1345     UnityConcludeTest();
1346 }
1347 
1348 /*-----------------------------------------------*/
UnityBegin(const char * filename)1349 void UnityBegin(const char* filename)
1350 {
1351     Unity.TestFile = filename;
1352     Unity.CurrentTestName = NULL;
1353     Unity.CurrentTestLineNumber = 0;
1354     Unity.NumberOfTests = 0;
1355     Unity.TestFailures = 0;
1356     Unity.TestIgnores = 0;
1357     Unity.CurrentTestFailed = 0;
1358     Unity.CurrentTestIgnored = 0;
1359 
1360     UNITY_CLR_DETAILS();
1361     UNITY_OUTPUT_START();
1362 }
1363 
1364 /*-----------------------------------------------*/
UnityEnd(void)1365 int UnityEnd(void)
1366 {
1367     UNITY_PRINT_EOL();
1368     UnityPrint(UnityStrBreaker);
1369     UNITY_PRINT_EOL();
1370     UnityPrintNumber((UNITY_INT)(Unity.NumberOfTests));
1371     UnityPrint(UnityStrResultsTests);
1372     UnityPrintNumber((UNITY_INT)(Unity.TestFailures));
1373     UnityPrint(UnityStrResultsFailures);
1374     UnityPrintNumber((UNITY_INT)(Unity.TestIgnores));
1375     UnityPrint(UnityStrResultsIgnored);
1376     UNITY_PRINT_EOL();
1377     if (Unity.TestFailures == 0U)
1378     {
1379         UnityPrint(UnityStrOk);
1380     }
1381     else
1382     {
1383         UnityPrint(UnityStrFail);
1384 #ifdef UNITY_DIFFERENTIATE_FINAL_FAIL
1385         UNITY_OUTPUT_CHAR('E'); UNITY_OUTPUT_CHAR('D');
1386 #endif
1387     }
1388     UNITY_PRINT_EOL();
1389     UNITY_FLUSH_CALL();
1390     UNITY_OUTPUT_COMPLETE();
1391     return (int)(Unity.TestFailures);
1392 }
1393 
1394 /*-----------------------------------------------
1395  * Command Line Argument Support
1396  *-----------------------------------------------*/
1397 #ifdef UNITY_USE_COMMAND_LINE_ARGS
1398 
1399 char* UnityOptionIncludeNamed = NULL;
1400 char* UnityOptionExcludeNamed = NULL;
1401 int UnityVerbosity            = 1;
1402 
UnityParseOptions(int argc,char ** argv)1403 int UnityParseOptions(int argc, char** argv)
1404 {
1405     UnityOptionIncludeNamed = NULL;
1406     UnityOptionExcludeNamed = NULL;
1407 
1408     for (int i = 1; i < argc; i++)
1409     {
1410         if (argv[i][0] == '-')
1411         {
1412             switch (argv[i][1])
1413             {
1414                 case 'l': /* list tests */
1415                     return -1;
1416                 case 'n': /* include tests with name including this string */
1417                 case 'f': /* an alias for -n */
1418                     if (argv[i][2] == '=')
1419                         UnityOptionIncludeNamed = &argv[i][3];
1420                     else if (++i < argc)
1421                         UnityOptionIncludeNamed = argv[i];
1422                     else
1423                     {
1424                         UnityPrint("ERROR: No Test String to Include Matches For");
1425                         UNITY_PRINT_EOL();
1426                         return 1;
1427                     }
1428                     break;
1429                 case 'q': /* quiet */
1430                     UnityVerbosity = 0;
1431                     break;
1432                 case 'v': /* verbose */
1433                     UnityVerbosity = 2;
1434                     break;
1435                 case 'x': /* exclude tests with name including this string */
1436                     if (argv[i][2] == '=')
1437                         UnityOptionExcludeNamed = &argv[i][3];
1438                     else if (++i < argc)
1439                         UnityOptionExcludeNamed = argv[i];
1440                     else
1441                     {
1442                         UnityPrint("ERROR: No Test String to Exclude Matches For");
1443                         UNITY_PRINT_EOL();
1444                         return 1;
1445                     }
1446                     break;
1447                 default:
1448                     UnityPrint("ERROR: Unknown Option ");
1449                     UNITY_OUTPUT_CHAR(argv[i][1]);
1450                     UNITY_PRINT_EOL();
1451                     return 1;
1452             }
1453         }
1454     }
1455 
1456     return 0;
1457 }
1458 
IsStringInBiggerString(const char * longstring,const char * shortstring)1459 int IsStringInBiggerString(const char* longstring, const char* shortstring)
1460 {
1461     const char* lptr = longstring;
1462     const char* sptr = shortstring;
1463     const char* lnext = lptr;
1464 
1465     if (*sptr == '*')
1466         return 1;
1467 
1468     while (*lptr)
1469     {
1470         lnext = lptr + 1;
1471 
1472         /* If they current bytes match, go on to the next bytes */
1473         while (*lptr && *sptr && (*lptr == *sptr))
1474         {
1475             lptr++;
1476             sptr++;
1477 
1478             /* We're done if we match the entire string or up to a wildcard */
1479             if (*sptr == '*')
1480                 return 1;
1481             if (*sptr == ',')
1482                 return 1;
1483             if (*sptr == '"')
1484                 return 1;
1485             if (*sptr == '\'')
1486                 return 1;
1487             if (*sptr == ':')
1488                 return 2;
1489             if (*sptr == 0)
1490                 return 1;
1491         }
1492 
1493         /* Otherwise we start in the long pointer 1 character further and try again */
1494         lptr = lnext;
1495         sptr = shortstring;
1496     }
1497     return 0;
1498 }
1499 
UnityStringArgumentMatches(const char * str)1500 int UnityStringArgumentMatches(const char* str)
1501 {
1502     int retval;
1503     const char* ptr1;
1504     const char* ptr2;
1505     const char* ptrf;
1506 
1507     /* Go through the options and get the substrings for matching one at a time */
1508     ptr1 = str;
1509     while (ptr1[0] != 0)
1510     {
1511         if ((ptr1[0] == '"') || (ptr1[0] == '\''))
1512             ptr1++;
1513 
1514         /* look for the start of the next partial */
1515         ptr2 = ptr1;
1516         ptrf = 0;
1517         do
1518         {
1519             ptr2++;
1520             if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ','))
1521                 ptrf = &ptr2[1];
1522         } while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ','));
1523         while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ',')))
1524             ptr2++;
1525 
1526         /* done if complete filename match */
1527         retval = IsStringInBiggerString(Unity.TestFile, ptr1);
1528         if (retval == 1)
1529             return retval;
1530 
1531         /* done if testname match after filename partial match */
1532         if ((retval == 2) && (ptrf != 0))
1533         {
1534             if (IsStringInBiggerString(Unity.CurrentTestName, ptrf))
1535                 return 1;
1536         }
1537 
1538         /* done if complete testname match */
1539         if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1)
1540             return 1;
1541 
1542         ptr1 = ptr2;
1543     }
1544 
1545     /* we couldn't find a match for any substrings */
1546     return 0;
1547 }
1548 
UnityTestMatches(void)1549 int UnityTestMatches(void)
1550 {
1551     /* Check if this test name matches the included test pattern */
1552     int retval;
1553     if (UnityOptionIncludeNamed)
1554     {
1555         retval = UnityStringArgumentMatches(UnityOptionIncludeNamed);
1556     }
1557     else
1558         retval = 1;
1559 
1560     /* Check if this test name matches the excluded test pattern */
1561     if (UnityOptionExcludeNamed)
1562     {
1563         if (UnityStringArgumentMatches(UnityOptionExcludeNamed))
1564             retval = 0;
1565     }
1566     return retval;
1567 }
1568 
1569 #endif /* UNITY_USE_COMMAND_LINE_ARGS */
1570 /*-----------------------------------------------*/
1571