1 /* =========================================================================
2     Unity Project - A Test Framework for C
3     Copyright (c) 2007-21 Mike Karlesky, Mark VanderVoord, Greg Williams
4     [Released under MIT License. Please refer to license.txt for details]
5 ============================================================================ */
6 #if LV_BUILD_TEST
7 #include "unity.h"
8 
9 #ifndef UNITY_PROGMEM
10 #define UNITY_PROGMEM
11 #endif
12 
13 /* If omitted from header, declare overridable prototypes here so they're ready for use */
14 #ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION
15 void UNITY_OUTPUT_CHAR(int);
16 #endif
17 
18 /* Helpful macros for us to use here in Assert functions */
19 #define UNITY_FAIL_AND_BAIL         do { Unity.CurrentTestFailed  = 1; UNITY_OUTPUT_FLUSH(); TEST_ABORT(); } while (0)
20 #define UNITY_IGNORE_AND_BAIL       do { Unity.CurrentTestIgnored = 1; UNITY_OUTPUT_FLUSH(); TEST_ABORT(); } while (0)
21 #define RETURN_IF_FAIL_OR_IGNORE    do { if (Unity.CurrentTestFailed || Unity.CurrentTestIgnored) { TEST_ABORT(); } } while (0)
22 
23 struct UNITY_STORAGE_T Unity;
24 
25 #ifdef UNITY_OUTPUT_COLOR
26 const char UNITY_PROGMEM UnityStrOk[]                            = "\033[42mOK\033[0m";
27 const char UNITY_PROGMEM UnityStrPass[]                          = "\033[42mPASS\033[0m";
28 const char UNITY_PROGMEM UnityStrFail[]                          = "\033[41mFAIL\033[0m";
29 const char UNITY_PROGMEM UnityStrIgnore[]                        = "\033[43mIGNORE\033[0m";
30 #else
31 const char UNITY_PROGMEM UnityStrOk[]                            = "OK";
32 const char UNITY_PROGMEM UnityStrPass[]                          = "PASS";
33 const char UNITY_PROGMEM UnityStrFail[]                          = "FAIL";
34 const char UNITY_PROGMEM UnityStrIgnore[]                        = "IGNORE";
35 #endif
36 static const char UNITY_PROGMEM UnityStrNull[]                   = "NULL";
37 static const char UNITY_PROGMEM UnityStrSpacer[]                 = ". ";
38 static const char UNITY_PROGMEM UnityStrExpected[]               = " Expected ";
39 static const char UNITY_PROGMEM UnityStrWas[]                    = " Was ";
40 static const char UNITY_PROGMEM UnityStrGt[]                     = " to be greater than ";
41 static const char UNITY_PROGMEM UnityStrLt[]                     = " to be less than ";
42 static const char UNITY_PROGMEM UnityStrOrEqual[]                = "or equal to ";
43 static const char UNITY_PROGMEM UnityStrNotEqual[]               = " to be not equal to ";
44 static const char UNITY_PROGMEM UnityStrElement[]                = " Element ";
45 static const char UNITY_PROGMEM UnityStrByte[]                   = " Byte ";
46 static const char UNITY_PROGMEM UnityStrMemory[]                 = " Memory Mismatch.";
47 static const char UNITY_PROGMEM UnityStrDelta[]                  = " Values Not Within Delta ";
48 static const char UNITY_PROGMEM UnityStrPointless[]              = " You Asked Me To Compare Nothing, Which Was Pointless.";
49 static const char UNITY_PROGMEM UnityStrNullPointerForExpected[] = " Expected pointer to be NULL";
50 static const char UNITY_PROGMEM UnityStrNullPointerForActual[]   = " Actual pointer was NULL";
51 #ifndef UNITY_EXCLUDE_FLOAT
52 static const char UNITY_PROGMEM UnityStrNot[]                    = "Not ";
53 static const char UNITY_PROGMEM UnityStrInf[]                    = "Infinity";
54 static const char UNITY_PROGMEM UnityStrNegInf[]                 = "Negative Infinity";
55 static const char UNITY_PROGMEM UnityStrNaN[]                    = "NaN";
56 static const char UNITY_PROGMEM UnityStrDet[]                    = "Determinate";
57 static const char UNITY_PROGMEM UnityStrInvalidFloatTrait[]      = "Invalid Float Trait";
58 #endif
59 const char UNITY_PROGMEM UnityStrErrShorthand[]                  = "Unity Shorthand Support Disabled";
60 const char UNITY_PROGMEM UnityStrErrFloat[]                      = "Unity Floating Point Disabled";
61 const char UNITY_PROGMEM UnityStrErrDouble[]                     = "Unity Double Precision Disabled";
62 const char UNITY_PROGMEM UnityStrErr64[]                         = "Unity 64-bit Support Disabled";
63 static const char UNITY_PROGMEM UnityStrBreaker[]                = "-----------------------";
64 static const char UNITY_PROGMEM UnityStrResultsTests[]           = " Tests ";
65 static const char UNITY_PROGMEM UnityStrResultsFailures[]        = " Failures ";
66 static const char UNITY_PROGMEM UnityStrResultsIgnored[]         = " Ignored ";
67 #ifndef UNITY_EXCLUDE_DETAILS
68 static const char UNITY_PROGMEM UnityStrDetail1Name[]            = UNITY_DETAIL1_NAME " ";
69 static const char UNITY_PROGMEM UnityStrDetail2Name[]            = " " UNITY_DETAIL2_NAME " ";
70 #endif
71 /*-----------------------------------------------
72  * Pretty Printers & Test Result Output Handlers
73  *-----------------------------------------------*/
74 
75 /*-----------------------------------------------*/
76 /* Local helper function to print characters. */
UnityPrintChar(const char * pch)77 static void UnityPrintChar(const char* pch)
78 {
79     /* printable characters plus CR & LF are printed */
80     if ((*pch <= 126) && (*pch >= 32))
81     {
82         UNITY_OUTPUT_CHAR(*pch);
83     }
84     /* write escaped carriage returns */
85     else if (*pch == 13)
86     {
87         UNITY_OUTPUT_CHAR('\\');
88         UNITY_OUTPUT_CHAR('r');
89     }
90     /* write escaped line feeds */
91     else if (*pch == 10)
92     {
93         UNITY_OUTPUT_CHAR('\\');
94         UNITY_OUTPUT_CHAR('n');
95     }
96     /* unprintable characters are shown as codes */
97     else
98     {
99         UNITY_OUTPUT_CHAR('\\');
100         UNITY_OUTPUT_CHAR('x');
101         UnityPrintNumberHex((UNITY_UINT)*pch, 2);
102     }
103 }
104 
105 /*-----------------------------------------------*/
106 /* Local helper function to print ANSI escape strings e.g. "\033[42m". */
107 #ifdef UNITY_OUTPUT_COLOR
UnityPrintAnsiEscapeString(const char * string)108 static UNITY_UINT UnityPrintAnsiEscapeString(const char* string)
109 {
110     const char* pch = string;
111     UNITY_UINT count = 0;
112 
113     while (*pch && (*pch != 'm'))
114     {
115         UNITY_OUTPUT_CHAR(*pch);
116         pch++;
117         count++;
118     }
119     UNITY_OUTPUT_CHAR('m');
120     count++;
121 
122     return count;
123 }
124 #endif
125 
126 /*-----------------------------------------------*/
UnityPrint(const char * string)127 void UnityPrint(const char* string)
128 {
129     const char* pch = string;
130 
131     if (pch != NULL)
132     {
133         while (*pch)
134         {
135 #ifdef UNITY_OUTPUT_COLOR
136             /* print ANSI escape code */
137             if ((*pch == 27) && (*(pch + 1) == '['))
138             {
139                 pch += UnityPrintAnsiEscapeString(pch);
140                 continue;
141             }
142 #endif
143             UnityPrintChar(pch);
144             pch++;
145         }
146     }
147 }
148 /*-----------------------------------------------*/
UnityPrintLen(const char * string,const UNITY_UINT32 length)149 void UnityPrintLen(const char* string, const UNITY_UINT32 length)
150 {
151     const char* pch = string;
152 
153     if (pch != NULL)
154     {
155         while (*pch && ((UNITY_UINT32)(pch - string) < length))
156         {
157             /* printable characters plus CR & LF are printed */
158             if ((*pch <= 126) && (*pch >= 32))
159             {
160                 UNITY_OUTPUT_CHAR(*pch);
161             }
162             /* write escaped carriage returns */
163             else if (*pch == 13)
164             {
165                 UNITY_OUTPUT_CHAR('\\');
166                 UNITY_OUTPUT_CHAR('r');
167             }
168             /* write escaped line feeds */
169             else if (*pch == 10)
170             {
171                 UNITY_OUTPUT_CHAR('\\');
172                 UNITY_OUTPUT_CHAR('n');
173             }
174             /* unprintable characters are shown as codes */
175             else
176             {
177                 UNITY_OUTPUT_CHAR('\\');
178                 UNITY_OUTPUT_CHAR('x');
179                 UnityPrintNumberHex((UNITY_UINT)*pch, 2);
180             }
181             pch++;
182         }
183     }
184 }
185 
186 /*-----------------------------------------------*/
UnityPrintNumberByStyle(const UNITY_INT number,const UNITY_DISPLAY_STYLE_T style)187 void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style)
188 {
189     if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
190     {
191         if (style == UNITY_DISPLAY_STYLE_CHAR)
192         {
193             /* printable characters plus CR & LF are printed */
194             UNITY_OUTPUT_CHAR('\'');
195             if ((number <= 126) && (number >= 32))
196             {
197                 UNITY_OUTPUT_CHAR((int)number);
198             }
199             /* write escaped carriage returns */
200             else if (number == 13)
201             {
202                 UNITY_OUTPUT_CHAR('\\');
203                 UNITY_OUTPUT_CHAR('r');
204             }
205             /* write escaped line feeds */
206             else if (number == 10)
207             {
208                 UNITY_OUTPUT_CHAR('\\');
209                 UNITY_OUTPUT_CHAR('n');
210             }
211             /* unprintable characters are shown as codes */
212             else
213             {
214                 UNITY_OUTPUT_CHAR('\\');
215                 UNITY_OUTPUT_CHAR('x');
216                 UnityPrintNumberHex((UNITY_UINT)number, 2);
217             }
218             UNITY_OUTPUT_CHAR('\'');
219         }
220         else
221         {
222             UnityPrintNumber(number);
223         }
224     }
225     else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT)
226     {
227         UnityPrintNumberUnsigned((UNITY_UINT)number);
228     }
229     else
230     {
231         UNITY_OUTPUT_CHAR('0');
232         UNITY_OUTPUT_CHAR('x');
233         UnityPrintNumberHex((UNITY_UINT)number, (char)((style & 0xF) * 2));
234     }
235 }
236 
237 /*-----------------------------------------------*/
UnityPrintNumber(const UNITY_INT number_to_print)238 void UnityPrintNumber(const UNITY_INT number_to_print)
239 {
240     UNITY_UINT number = (UNITY_UINT)number_to_print;
241 
242     if (number_to_print < 0)
243     {
244         /* A negative number, including MIN negative */
245         UNITY_OUTPUT_CHAR('-');
246         number = (~number) + 1;
247     }
248     UnityPrintNumberUnsigned(number);
249 }
250 
251 /*-----------------------------------------------
252  * basically do an itoa using as little ram as possible */
UnityPrintNumberUnsigned(const UNITY_UINT number)253 void UnityPrintNumberUnsigned(const UNITY_UINT number)
254 {
255     UNITY_UINT divisor = 1;
256 
257     /* figure out initial divisor */
258     while (number / divisor > 9)
259     {
260         divisor *= 10;
261     }
262 
263     /* now mod and print, then divide divisor */
264     do
265     {
266         UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
267         divisor /= 10;
268     } while (divisor > 0);
269 }
270 
271 /*-----------------------------------------------*/
UnityPrintNumberHex(const UNITY_UINT number,const char nibbles_to_print)272 void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print)
273 {
274     int nibble;
275     char nibbles = nibbles_to_print;
276 
277     if ((unsigned)nibbles > UNITY_MAX_NIBBLES)
278     {
279         nibbles = UNITY_MAX_NIBBLES;
280     }
281 
282     while (nibbles > 0)
283     {
284         nibbles--;
285         nibble = (int)(number >> (nibbles * 4)) & 0x0F;
286         if (nibble <= 9)
287         {
288             UNITY_OUTPUT_CHAR((char)('0' + nibble));
289         }
290         else
291         {
292             UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble));
293         }
294     }
295 }
296 
297 /*-----------------------------------------------*/
UnityPrintMask(const UNITY_UINT mask,const UNITY_UINT number)298 void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number)
299 {
300     UNITY_UINT current_bit = (UNITY_UINT)1 << (UNITY_INT_WIDTH - 1);
301     UNITY_INT32 i;
302 
303     for (i = 0; i < UNITY_INT_WIDTH; i++)
304     {
305         if (current_bit & mask)
306         {
307             if (current_bit & number)
308             {
309                 UNITY_OUTPUT_CHAR('1');
310             }
311             else
312             {
313                 UNITY_OUTPUT_CHAR('0');
314             }
315         }
316         else
317         {
318             UNITY_OUTPUT_CHAR('X');
319         }
320         current_bit = current_bit >> 1;
321     }
322 }
323 
324 /*-----------------------------------------------*/
325 #ifndef UNITY_EXCLUDE_FLOAT_PRINT
326 /*
327  * This function prints a floating-point value in a format similar to
328  * printf("%.7g") on a single-precision machine or printf("%.9g") on a
329  * double-precision machine.  The 7th digit won't always be totally correct
330  * in single-precision operation (for that level of accuracy, a more
331  * complicated algorithm would be needed).
332  */
UnityPrintFloat(const UNITY_DOUBLE input_number)333 void UnityPrintFloat(const UNITY_DOUBLE input_number)
334 {
335 #ifdef UNITY_INCLUDE_DOUBLE
336     static const int sig_digits = 9;
337     static const UNITY_INT32 min_scaled = 100000000;
338     static const UNITY_INT32 max_scaled = 1000000000;
339 #else
340     static const int sig_digits = 7;
341     static const UNITY_INT32 min_scaled = 1000000;
342     static const UNITY_INT32 max_scaled = 10000000;
343 #endif
344 
345     UNITY_DOUBLE number = input_number;
346 
347     /* print minus sign (does not handle negative zero) */
348     if (number < 0.0f)
349     {
350         UNITY_OUTPUT_CHAR('-');
351         number = -number;
352     }
353 
354     /* handle zero, NaN, and +/- infinity */
355     if (number == 0.0f)
356     {
357         UnityPrint("0");
358     }
359     else if (UNITY_IS_NAN(number))
360     {
361         UnityPrint("nan");
362     }
363     else if (UNITY_IS_INF(number))
364     {
365         UnityPrint("inf");
366     }
367     else
368     {
369         UNITY_INT32 n_int = 0;
370         UNITY_INT32 n;
371         int         exponent = 0;
372         int         decimals;
373         int         digits;
374         char        buf[16] = {0};
375 
376         /*
377          * Scale up or down by powers of 10.  To minimize rounding error,
378          * start with a factor/divisor of 10^10, which is the largest
379          * power of 10 that can be represented exactly.  Finally, compute
380          * (exactly) the remaining power of 10 and perform one more
381          * multiplication or division.
382          */
383         if (number < 1.0f)
384         {
385             UNITY_DOUBLE factor = 1.0f;
386 
387             while (number < (UNITY_DOUBLE)max_scaled / 1e10f)  { number *= 1e10f; exponent -= 10; }
388             while (number * factor < (UNITY_DOUBLE)min_scaled) { factor *= 10.0f; exponent--; }
389 
390             number *= factor;
391         }
392         else if (number > (UNITY_DOUBLE)max_scaled)
393         {
394             UNITY_DOUBLE divisor = 1.0f;
395 
396             while (number > (UNITY_DOUBLE)min_scaled * 1e10f)   { number  /= 1e10f; exponent += 10; }
397             while (number / divisor > (UNITY_DOUBLE)max_scaled) { divisor *= 10.0f; exponent++; }
398 
399             number /= divisor;
400         }
401         else
402         {
403             /*
404              * In this range, we can split off the integer part before
405              * doing any multiplications.  This reduces rounding error by
406              * freeing up significant bits in the fractional part.
407              */
408             UNITY_DOUBLE factor = 1.0f;
409             n_int = (UNITY_INT32)number;
410             number -= (UNITY_DOUBLE)n_int;
411 
412             while (n_int < min_scaled) { n_int *= 10; factor *= 10.0f; exponent--; }
413 
414             number *= factor;
415         }
416 
417         /* round to nearest integer */
418         n = ((UNITY_INT32)(number + number) + 1) / 2;
419 
420 #ifndef UNITY_ROUND_TIES_AWAY_FROM_ZERO
421         /* round to even if exactly between two integers */
422         if ((n & 1) && (((UNITY_DOUBLE)n - number) == 0.5f))
423             n--;
424 #endif
425 
426         n += n_int;
427 
428         if (n >= max_scaled)
429         {
430             n = min_scaled;
431             exponent++;
432         }
433 
434         /* determine where to place decimal point */
435         decimals = ((exponent <= 0) && (exponent >= -(sig_digits + 3))) ? (-exponent) : (sig_digits - 1);
436         exponent += decimals;
437 
438         /* truncate trailing zeroes after decimal point */
439         while ((decimals > 0) && ((n % 10) == 0))
440         {
441             n /= 10;
442             decimals--;
443         }
444 
445         /* build up buffer in reverse order */
446         digits = 0;
447         while ((n != 0) || (digits <= decimals))
448         {
449             buf[digits++] = (char)('0' + n % 10);
450             n /= 10;
451         }
452 
453         /* print out buffer (backwards) */
454         while (digits > 0)
455         {
456             if (digits == decimals)
457             {
458                 UNITY_OUTPUT_CHAR('.');
459             }
460             UNITY_OUTPUT_CHAR(buf[--digits]);
461         }
462 
463         /* print exponent if needed */
464         if (exponent != 0)
465         {
466             UNITY_OUTPUT_CHAR('e');
467 
468             if (exponent < 0)
469             {
470                 UNITY_OUTPUT_CHAR('-');
471                 exponent = -exponent;
472             }
473             else
474             {
475                 UNITY_OUTPUT_CHAR('+');
476             }
477 
478             digits = 0;
479             while ((exponent != 0) || (digits < 2))
480             {
481                 buf[digits++] = (char)('0' + exponent % 10);
482                 exponent /= 10;
483             }
484             while (digits > 0)
485             {
486                 UNITY_OUTPUT_CHAR(buf[--digits]);
487             }
488         }
489     }
490 }
491 #endif /* ! UNITY_EXCLUDE_FLOAT_PRINT */
492 
493 /*-----------------------------------------------*/
UnityTestResultsBegin(const char * file,const UNITY_LINE_TYPE line)494 static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line)
495 {
496 #ifdef UNITY_OUTPUT_FOR_ECLIPSE
497     UNITY_OUTPUT_CHAR('(');
498     UnityPrint(file);
499     UNITY_OUTPUT_CHAR(':');
500     UnityPrintNumber((UNITY_INT)line);
501     UNITY_OUTPUT_CHAR(')');
502     UNITY_OUTPUT_CHAR(' ');
503     UnityPrint(Unity.CurrentTestName);
504     UNITY_OUTPUT_CHAR(':');
505 #else
506 #ifdef UNITY_OUTPUT_FOR_IAR_WORKBENCH
507     UnityPrint("<SRCREF line=");
508     UnityPrintNumber((UNITY_INT)line);
509     UnityPrint(" file=\"");
510     UnityPrint(file);
511     UNITY_OUTPUT_CHAR('"');
512     UNITY_OUTPUT_CHAR('>');
513     UnityPrint(Unity.CurrentTestName);
514     UnityPrint("</SRCREF> ");
515 #else
516 #ifdef UNITY_OUTPUT_FOR_QT_CREATOR
517     UnityPrint("file://");
518     UnityPrint(file);
519     UNITY_OUTPUT_CHAR(':');
520     UnityPrintNumber((UNITY_INT)line);
521     UNITY_OUTPUT_CHAR(' ');
522     UnityPrint(Unity.CurrentTestName);
523     UNITY_OUTPUT_CHAR(':');
524 #else
525     UnityPrint(file);
526     UNITY_OUTPUT_CHAR(':');
527     UnityPrintNumber((UNITY_INT)line);
528     UNITY_OUTPUT_CHAR(':');
529     UnityPrint(Unity.CurrentTestName);
530     UNITY_OUTPUT_CHAR(':');
531 #endif
532 #endif
533 #endif
534 }
535 
536 /*-----------------------------------------------*/
UnityTestResultsFailBegin(const UNITY_LINE_TYPE line)537 static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line)
538 {
539     UnityTestResultsBegin(Unity.TestFile, line);
540     UnityPrint(UnityStrFail);
541     UNITY_OUTPUT_CHAR(':');
542 }
543 
544 /*-----------------------------------------------*/
UnityConcludeTest(void)545 void UnityConcludeTest(void)
546 {
547     if (Unity.CurrentTestIgnored)
548     {
549         Unity.TestIgnores++;
550     }
551     else if (!Unity.CurrentTestFailed)
552     {
553         UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber);
554         UnityPrint(UnityStrPass);
555     }
556     else
557     {
558         Unity.TestFailures++;
559     }
560 
561     Unity.CurrentTestFailed = 0;
562     Unity.CurrentTestIgnored = 0;
563     UNITY_PRINT_EXEC_TIME();
564     UNITY_PRINT_EOL();
565     UNITY_FLUSH_CALL();
566 }
567 
568 /*-----------------------------------------------*/
UnityAddMsgIfSpecified(const char * msg)569 static void UnityAddMsgIfSpecified(const char* msg)
570 {
571 #ifdef UNITY_PRINT_TEST_CONTEXT
572     UnityPrint(UnityStrSpacer);
573     UNITY_PRINT_TEST_CONTEXT();
574 #endif
575 #ifndef UNITY_EXCLUDE_DETAILS
576     if (Unity.CurrentDetail1)
577     {
578         UnityPrint(UnityStrSpacer);
579         UnityPrint(UnityStrDetail1Name);
580         UnityPrint(Unity.CurrentDetail1);
581         if (Unity.CurrentDetail2)
582         {
583             UnityPrint(UnityStrDetail2Name);
584             UnityPrint(Unity.CurrentDetail2);
585         }
586     }
587 #endif
588     if (msg)
589     {
590         UnityPrint(UnityStrSpacer);
591         UnityPrint(msg);
592     }
593 }
594 
595 /*-----------------------------------------------*/
UnityPrintExpectedAndActualStrings(const char * expected,const char * actual)596 static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual)
597 {
598     UnityPrint(UnityStrExpected);
599     if (expected != NULL)
600     {
601         UNITY_OUTPUT_CHAR('\'');
602         UnityPrint(expected);
603         UNITY_OUTPUT_CHAR('\'');
604     }
605     else
606     {
607         UnityPrint(UnityStrNull);
608     }
609     UnityPrint(UnityStrWas);
610     if (actual != NULL)
611     {
612         UNITY_OUTPUT_CHAR('\'');
613         UnityPrint(actual);
614         UNITY_OUTPUT_CHAR('\'');
615     }
616     else
617     {
618         UnityPrint(UnityStrNull);
619     }
620 }
621 
622 /*-----------------------------------------------*/
UnityPrintExpectedAndActualStringsLen(const char * expected,const char * actual,const UNITY_UINT32 length)623 static void UnityPrintExpectedAndActualStringsLen(const char* expected,
624                                                   const char* actual,
625                                                   const UNITY_UINT32 length)
626 {
627     UnityPrint(UnityStrExpected);
628     if (expected != NULL)
629     {
630         UNITY_OUTPUT_CHAR('\'');
631         UnityPrintLen(expected, length);
632         UNITY_OUTPUT_CHAR('\'');
633     }
634     else
635     {
636         UnityPrint(UnityStrNull);
637     }
638     UnityPrint(UnityStrWas);
639     if (actual != NULL)
640     {
641         UNITY_OUTPUT_CHAR('\'');
642         UnityPrintLen(actual, length);
643         UNITY_OUTPUT_CHAR('\'');
644     }
645     else
646     {
647         UnityPrint(UnityStrNull);
648     }
649 }
650 
651 /*-----------------------------------------------
652  * Assertion & Control Helpers
653  *-----------------------------------------------*/
654 
655 /*-----------------------------------------------*/
UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected,UNITY_INTERNAL_PTR actual,const UNITY_LINE_TYPE lineNumber,const char * msg)656 static int UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected,
657                                UNITY_INTERNAL_PTR actual,
658                                const UNITY_LINE_TYPE lineNumber,
659                                const char* msg)
660 {
661     /* Both are NULL or same pointer */
662     if (expected == actual) { return 0; }
663 
664     /* print and return true if just expected is NULL */
665     if (expected == NULL)
666     {
667         UnityTestResultsFailBegin(lineNumber);
668         UnityPrint(UnityStrNullPointerForExpected);
669         UnityAddMsgIfSpecified(msg);
670         return 1;
671     }
672 
673     /* print and return true if just actual is NULL */
674     if (actual == NULL)
675     {
676         UnityTestResultsFailBegin(lineNumber);
677         UnityPrint(UnityStrNullPointerForActual);
678         UnityAddMsgIfSpecified(msg);
679         return 1;
680     }
681 
682     return 0; /* return false if neither is NULL */
683 }
684 
685 /*-----------------------------------------------
686  * Assertion Functions
687  *-----------------------------------------------*/
688 
689 /*-----------------------------------------------*/
UnityAssertBits(const UNITY_INT mask,const UNITY_INT expected,const UNITY_INT actual,const char * msg,const UNITY_LINE_TYPE lineNumber)690 void UnityAssertBits(const UNITY_INT mask,
691                      const UNITY_INT expected,
692                      const UNITY_INT actual,
693                      const char* msg,
694                      const UNITY_LINE_TYPE lineNumber)
695 {
696     RETURN_IF_FAIL_OR_IGNORE;
697 
698     if ((mask & expected) != (mask & actual))
699     {
700         UnityTestResultsFailBegin(lineNumber);
701         UnityPrint(UnityStrExpected);
702         UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)expected);
703         UnityPrint(UnityStrWas);
704         UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)actual);
705         UnityAddMsgIfSpecified(msg);
706         UNITY_FAIL_AND_BAIL;
707     }
708 }
709 
710 /*-----------------------------------------------*/
UnityAssertEqualNumber(const UNITY_INT expected,const UNITY_INT actual,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_DISPLAY_STYLE_T style)711 void UnityAssertEqualNumber(const UNITY_INT expected,
712                             const UNITY_INT actual,
713                             const char* msg,
714                             const UNITY_LINE_TYPE lineNumber,
715                             const UNITY_DISPLAY_STYLE_T style)
716 {
717     RETURN_IF_FAIL_OR_IGNORE;
718 
719     if (expected != actual)
720     {
721         UnityTestResultsFailBegin(lineNumber);
722         UnityPrint(UnityStrExpected);
723         UnityPrintNumberByStyle(expected, style);
724         UnityPrint(UnityStrWas);
725         UnityPrintNumberByStyle(actual, style);
726         UnityAddMsgIfSpecified(msg);
727         UNITY_FAIL_AND_BAIL;
728     }
729 }
730 
731 /*-----------------------------------------------*/
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)732 void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold,
733                                            const UNITY_INT actual,
734                                            const UNITY_COMPARISON_T compare,
735                                            const char *msg,
736                                            const UNITY_LINE_TYPE lineNumber,
737                                            const UNITY_DISPLAY_STYLE_T style)
738 {
739     int failed = 0;
740     RETURN_IF_FAIL_OR_IGNORE;
741 
742     if ((threshold == actual) && (compare & UNITY_EQUAL_TO)) { return; }
743     if ((threshold == actual))                               { failed = 1; }
744 
745     if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
746     {
747         if ((actual > threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; }
748         if ((actual < threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; }
749     }
750     else /* UINT or HEX */
751     {
752         if (((UNITY_UINT)actual > (UNITY_UINT)threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; }
753         if (((UNITY_UINT)actual < (UNITY_UINT)threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; }
754     }
755 
756     if (failed)
757     {
758         UnityTestResultsFailBegin(lineNumber);
759         UnityPrint(UnityStrExpected);
760         UnityPrintNumberByStyle(actual, style);
761         if (compare & UNITY_GREATER_THAN) { UnityPrint(UnityStrGt);       }
762         if (compare & UNITY_SMALLER_THAN) { UnityPrint(UnityStrLt);       }
763         if (compare & UNITY_EQUAL_TO)     { UnityPrint(UnityStrOrEqual);  }
764         if (compare == UNITY_NOT_EQUAL)   { UnityPrint(UnityStrNotEqual); }
765         UnityPrintNumberByStyle(threshold, style);
766         UnityAddMsgIfSpecified(msg);
767         UNITY_FAIL_AND_BAIL;
768     }
769 }
770 
771 #define UnityPrintPointlessAndBail()       \
772 do {                                       \
773     UnityTestResultsFailBegin(lineNumber); \
774     UnityPrint(UnityStrPointless);         \
775     UnityAddMsgIfSpecified(msg);           \
776     UNITY_FAIL_AND_BAIL;                   \
777 } while (0)
778 
779 /*-----------------------------------------------*/
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)780 void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
781                               UNITY_INTERNAL_PTR actual,
782                               const UNITY_UINT32 num_elements,
783                               const char* msg,
784                               const UNITY_LINE_TYPE lineNumber,
785                               const UNITY_DISPLAY_STYLE_T style,
786                               const UNITY_FLAGS_T flags)
787 {
788     UNITY_UINT32 elements  = num_elements;
789     unsigned int length    = style & 0xF;
790     unsigned int increment = 0;
791 
792     RETURN_IF_FAIL_OR_IGNORE;
793 
794     if (num_elements == 0)
795     {
796 #ifdef UNITY_COMPARE_PTRS_ON_ZERO_ARRAY
797         UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, lineNumber, msg);
798 #else
799         UnityPrintPointlessAndBail();
800 #endif
801     }
802 
803     if (expected == actual)
804     {
805         return; /* Both are NULL or same pointer */
806     }
807 
808     if (UnityIsOneArrayNull(expected, actual, lineNumber, msg))
809     {
810         UNITY_FAIL_AND_BAIL;
811     }
812 
813     while ((elements > 0) && (elements--))
814     {
815         UNITY_INT expect_val;
816         UNITY_INT actual_val;
817 
818         switch (length)
819         {
820             case 1:
821                 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected;
822                 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual;
823                 if (style & (UNITY_DISPLAY_RANGE_UINT | UNITY_DISPLAY_RANGE_HEX))
824                 {
825                     expect_val &= 0x000000FF;
826                     actual_val &= 0x000000FF;
827                 }
828                 increment  = sizeof(UNITY_INT8);
829                 break;
830 
831             case 2:
832                 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected;
833                 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual;
834                 if (style & (UNITY_DISPLAY_RANGE_UINT | UNITY_DISPLAY_RANGE_HEX))
835                 {
836                     expect_val &= 0x0000FFFF;
837                     actual_val &= 0x0000FFFF;
838                 }
839                 increment  = sizeof(UNITY_INT16);
840                 break;
841 
842 #ifdef UNITY_SUPPORT_64
843             case 8:
844                 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected;
845                 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual;
846                 increment  = sizeof(UNITY_INT64);
847                 break;
848 #endif
849 
850             default: /* default is length 4 bytes */
851             case 4:
852                 expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected;
853                 actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual;
854 #ifdef UNITY_SUPPORT_64
855                 if (style & (UNITY_DISPLAY_RANGE_UINT | UNITY_DISPLAY_RANGE_HEX))
856                 {
857                     expect_val &= 0x00000000FFFFFFFF;
858                     actual_val &= 0x00000000FFFFFFFF;
859                 }
860 #endif
861                 increment  = sizeof(UNITY_INT32);
862                 length = 4;
863                 break;
864         }
865 
866         if (expect_val != actual_val)
867         {
868             if ((style & UNITY_DISPLAY_RANGE_UINT) && (length < (UNITY_INT_WIDTH / 8)))
869             {   /* For UINT, remove sign extension (padding 1's) from signed type casts above */
870                 UNITY_INT mask = 1;
871                 mask = (mask << 8 * length) - 1;
872                 expect_val &= mask;
873                 actual_val &= mask;
874             }
875             UnityTestResultsFailBegin(lineNumber);
876             UnityPrint(UnityStrElement);
877             UnityPrintNumberUnsigned(num_elements - elements - 1);
878             UnityPrint(UnityStrExpected);
879             UnityPrintNumberByStyle(expect_val, style);
880             UnityPrint(UnityStrWas);
881             UnityPrintNumberByStyle(actual_val, style);
882             UnityAddMsgIfSpecified(msg);
883             UNITY_FAIL_AND_BAIL;
884         }
885         /* Walk through array by incrementing the pointers */
886         if (flags == UNITY_ARRAY_TO_ARRAY)
887         {
888             expected = (UNITY_INTERNAL_PTR)((const char*)expected + increment);
889         }
890         actual = (UNITY_INTERNAL_PTR)((const char*)actual + increment);
891     }
892 }
893 
894 /*-----------------------------------------------*/
895 #ifndef UNITY_EXCLUDE_FLOAT
896 /* Wrap this define in a function with variable types as float or double */
897 #define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff)                           \
898     if (UNITY_IS_INF(expected) && UNITY_IS_INF(actual) && (((expected) < 0) == ((actual) < 0))) return 1;   \
899     if (UNITY_NAN_CHECK) return 1;                                                            \
900     (diff) = (actual) - (expected);                                                           \
901     if ((diff) < 0) (diff) = -(diff);                                                         \
902     if ((delta) < 0) (delta) = -(delta);                                                      \
903     return !(UNITY_IS_NAN(diff) || UNITY_IS_INF(diff) || ((diff) > (delta)))
904     /* This first part of this condition will catch any NaN or Infinite values */
905 #ifndef UNITY_NAN_NOT_EQUAL_NAN
906   #define UNITY_NAN_CHECK UNITY_IS_NAN(expected) && UNITY_IS_NAN(actual)
907 #else
908   #define UNITY_NAN_CHECK 0
909 #endif
910 
911 #ifndef UNITY_EXCLUDE_FLOAT_PRINT
912   #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \
913   do {                                                            \
914     UnityPrint(UnityStrExpected);                                 \
915     UnityPrintFloat(expected);                                    \
916     UnityPrint(UnityStrWas);                                      \
917     UnityPrintFloat(actual);                                      \
918   } while (0)
919 #else
920   #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \
921     UnityPrint(UnityStrDelta)
922 #endif /* UNITY_EXCLUDE_FLOAT_PRINT */
923 
924 /*-----------------------------------------------*/
UnityFloatsWithin(UNITY_FLOAT delta,UNITY_FLOAT expected,UNITY_FLOAT actual)925 static int UnityFloatsWithin(UNITY_FLOAT delta, UNITY_FLOAT expected, UNITY_FLOAT actual)
926 {
927     UNITY_FLOAT diff;
928     UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff);
929 }
930 
931 /*-----------------------------------------------*/
UnityAssertWithinFloatArray(const UNITY_FLOAT delta,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)932 void UnityAssertWithinFloatArray(const UNITY_FLOAT delta,
933                                  UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected,
934                                  UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual,
935                                  const UNITY_UINT32 num_elements,
936                                  const char* msg,
937                                  const UNITY_LINE_TYPE lineNumber,
938                                  const UNITY_FLAGS_T flags)
939 {
940     UNITY_UINT32 elements = num_elements;
941     UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_expected = expected;
942     UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_actual = actual;
943     UNITY_FLOAT in_delta = delta;
944     UNITY_FLOAT current_element_delta = delta;
945 
946     RETURN_IF_FAIL_OR_IGNORE;
947 
948     if (elements == 0)
949     {
950 #ifdef UNITY_COMPARE_PTRS_ON_ZERO_ARRAY
951         UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, lineNumber, msg);
952 #else
953         UnityPrintPointlessAndBail();
954 #endif
955     }
956 
957     if (UNITY_IS_INF(in_delta))
958     {
959         return; /* Arrays will be force equal with infinite delta */
960     }
961 
962     if (UNITY_IS_NAN(in_delta))
963     {
964         /* Delta must be correct number */
965         UnityPrintPointlessAndBail();
966     }
967 
968     if (expected == actual)
969     {
970         return; /* Both are NULL or same pointer */
971     }
972 
973     if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
974     {
975         UNITY_FAIL_AND_BAIL;
976     }
977 
978     /* fix delta sign if need */
979     if (in_delta < 0)
980     {
981         in_delta = -in_delta;
982     }
983 
984     while (elements--)
985     {
986         current_element_delta = *ptr_expected * UNITY_FLOAT_PRECISION;
987 
988         if (current_element_delta < 0)
989         {
990             /* fix delta sign for correct calculations */
991             current_element_delta = -current_element_delta;
992         }
993 
994         if (!UnityFloatsWithin(in_delta + current_element_delta, *ptr_expected, *ptr_actual))
995         {
996             UnityTestResultsFailBegin(lineNumber);
997             UnityPrint(UnityStrElement);
998             UnityPrintNumberUnsigned(num_elements - elements - 1);
999             UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)*ptr_expected, (UNITY_DOUBLE)*ptr_actual);
1000             UnityAddMsgIfSpecified(msg);
1001             UNITY_FAIL_AND_BAIL;
1002         }
1003         if (flags == UNITY_ARRAY_TO_ARRAY)
1004         {
1005             ptr_expected++;
1006         }
1007         ptr_actual++;
1008     }
1009 }
1010 
1011 /*-----------------------------------------------*/
UnityAssertFloatsWithin(const UNITY_FLOAT delta,const UNITY_FLOAT expected,const UNITY_FLOAT actual,const char * msg,const UNITY_LINE_TYPE lineNumber)1012 void UnityAssertFloatsWithin(const UNITY_FLOAT delta,
1013                              const UNITY_FLOAT expected,
1014                              const UNITY_FLOAT actual,
1015                              const char* msg,
1016                              const UNITY_LINE_TYPE lineNumber)
1017 {
1018     RETURN_IF_FAIL_OR_IGNORE;
1019 
1020 
1021     if (!UnityFloatsWithin(delta, expected, actual))
1022     {
1023         UnityTestResultsFailBegin(lineNumber);
1024         UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual);
1025         UnityAddMsgIfSpecified(msg);
1026         UNITY_FAIL_AND_BAIL;
1027     }
1028 }
1029 
1030 /*-----------------------------------------------*/
UnityAssertFloatsNotWithin(const UNITY_FLOAT delta,const UNITY_FLOAT expected,const UNITY_FLOAT actual,const char * msg,const UNITY_LINE_TYPE lineNumber)1031 void UnityAssertFloatsNotWithin(const UNITY_FLOAT delta,
1032                                 const UNITY_FLOAT expected,
1033                                 const UNITY_FLOAT actual,
1034                                 const char* msg,
1035                                 const UNITY_LINE_TYPE lineNumber)
1036 {
1037     RETURN_IF_FAIL_OR_IGNORE;
1038 
1039     if (UnityFloatsWithin(delta, expected, actual))
1040     {
1041         UnityTestResultsFailBegin(lineNumber);
1042         UnityPrint(UnityStrExpected);
1043         UnityPrintFloat((UNITY_DOUBLE)expected);
1044         UnityPrint(UnityStrNotEqual);
1045         UnityPrintFloat((UNITY_DOUBLE)actual);
1046         UnityAddMsgIfSpecified(msg);
1047         UNITY_FAIL_AND_BAIL;
1048     }
1049 }
1050 
1051 /*-----------------------------------------------*/
UnityAssertGreaterOrLessFloat(const UNITY_FLOAT threshold,const UNITY_FLOAT actual,const UNITY_COMPARISON_T compare,const char * msg,const UNITY_LINE_TYPE lineNumber)1052 void UnityAssertGreaterOrLessFloat(const UNITY_FLOAT threshold,
1053                                    const UNITY_FLOAT actual,
1054                                    const UNITY_COMPARISON_T compare,
1055                                    const char* msg,
1056                                    const UNITY_LINE_TYPE lineNumber)
1057 {
1058     int failed;
1059 
1060     RETURN_IF_FAIL_OR_IGNORE;
1061 
1062     failed = 0;
1063 
1064     /* Checking for "not success" rather than failure to get the right result for NaN */
1065     if (!(actual < threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; }
1066     if (!(actual > threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; }
1067 
1068     if ((compare & UNITY_EQUAL_TO) && UnityFloatsWithin(threshold * UNITY_FLOAT_PRECISION, threshold, actual)) { failed = 0; }
1069 
1070     if (failed)
1071     {
1072         UnityTestResultsFailBegin(lineNumber);
1073         UnityPrint(UnityStrExpected);
1074         UnityPrintFloat(actual);
1075         if (compare & UNITY_GREATER_THAN) { UnityPrint(UnityStrGt); }
1076         if (compare & UNITY_SMALLER_THAN) { UnityPrint(UnityStrLt); }
1077         if (compare & UNITY_EQUAL_TO)     { UnityPrint(UnityStrOrEqual);  }
1078         UnityPrintFloat(threshold);
1079         UnityAddMsgIfSpecified(msg);
1080         UNITY_FAIL_AND_BAIL;
1081     }
1082 }
1083 
1084 /*-----------------------------------------------*/
UnityAssertFloatSpecial(const UNITY_FLOAT actual,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLOAT_TRAIT_T style)1085 void UnityAssertFloatSpecial(const UNITY_FLOAT actual,
1086                              const char* msg,
1087                              const UNITY_LINE_TYPE lineNumber,
1088                              const UNITY_FLOAT_TRAIT_T style)
1089 {
1090     const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet};
1091     UNITY_INT should_be_trait = ((UNITY_INT)style & 1);
1092     UNITY_INT is_trait        = !should_be_trait;
1093     UNITY_INT trait_index     = (UNITY_INT)(style >> 1);
1094 
1095     RETURN_IF_FAIL_OR_IGNORE;
1096 
1097     switch (style)
1098     {
1099         case UNITY_FLOAT_IS_INF:
1100         case UNITY_FLOAT_IS_NOT_INF:
1101             is_trait = UNITY_IS_INF(actual) && (actual > 0);
1102             break;
1103         case UNITY_FLOAT_IS_NEG_INF:
1104         case UNITY_FLOAT_IS_NOT_NEG_INF:
1105             is_trait = UNITY_IS_INF(actual) && (actual < 0);
1106             break;
1107 
1108         case UNITY_FLOAT_IS_NAN:
1109         case UNITY_FLOAT_IS_NOT_NAN:
1110             is_trait = UNITY_IS_NAN(actual) ? 1 : 0;
1111             break;
1112 
1113         case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */
1114         case UNITY_FLOAT_IS_NOT_DET:
1115             is_trait = !UNITY_IS_INF(actual) && !UNITY_IS_NAN(actual);
1116             break;
1117 
1118         case UNITY_FLOAT_INVALID_TRAIT:  /* Supress warning */
1119         default: /* including UNITY_FLOAT_INVALID_TRAIT */
1120             trait_index = 0;
1121             trait_names[0] = UnityStrInvalidFloatTrait;
1122             break;
1123     }
1124 
1125     if (is_trait != should_be_trait)
1126     {
1127         UnityTestResultsFailBegin(lineNumber);
1128         UnityPrint(UnityStrExpected);
1129         if (!should_be_trait)
1130         {
1131             UnityPrint(UnityStrNot);
1132         }
1133         UnityPrint(trait_names[trait_index]);
1134         UnityPrint(UnityStrWas);
1135 #ifndef UNITY_EXCLUDE_FLOAT_PRINT
1136         UnityPrintFloat((UNITY_DOUBLE)actual);
1137 #else
1138         if (should_be_trait)
1139         {
1140             UnityPrint(UnityStrNot);
1141         }
1142         UnityPrint(trait_names[trait_index]);
1143 #endif
1144         UnityAddMsgIfSpecified(msg);
1145         UNITY_FAIL_AND_BAIL;
1146     }
1147 }
1148 
1149 #endif /* not UNITY_EXCLUDE_FLOAT */
1150 
1151 /*-----------------------------------------------*/
1152 #ifndef UNITY_EXCLUDE_DOUBLE
UnityDoublesWithin(UNITY_DOUBLE delta,UNITY_DOUBLE expected,UNITY_DOUBLE actual)1153 static int UnityDoublesWithin(UNITY_DOUBLE delta, UNITY_DOUBLE expected, UNITY_DOUBLE actual)
1154 {
1155     UNITY_DOUBLE diff;
1156     UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff);
1157 }
1158 
1159 /*-----------------------------------------------*/
UnityAssertWithinDoubleArray(const UNITY_DOUBLE delta,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)1160 void UnityAssertWithinDoubleArray(const UNITY_DOUBLE delta,
1161                                   UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected,
1162                                   UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual,
1163                                   const UNITY_UINT32 num_elements,
1164                                   const char* msg,
1165                                   const UNITY_LINE_TYPE lineNumber,
1166                                   const UNITY_FLAGS_T flags)
1167 {
1168     UNITY_UINT32 elements = num_elements;
1169     UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_expected = expected;
1170     UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_actual = actual;
1171     UNITY_DOUBLE in_delta = delta;
1172     UNITY_DOUBLE current_element_delta = delta;
1173 
1174     RETURN_IF_FAIL_OR_IGNORE;
1175 
1176     if (elements == 0)
1177     {
1178 #ifdef UNITY_COMPARE_PTRS_ON_ZERO_ARRAY
1179         UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, lineNumber, msg);
1180 #else
1181         UnityPrintPointlessAndBail();
1182 #endif
1183     }
1184 
1185     if (UNITY_IS_INF(in_delta))
1186     {
1187         return; /* Arrays will be force equal with infinite delta */
1188     }
1189 
1190     if (UNITY_IS_NAN(in_delta))
1191     {
1192         /* Delta must be correct number */
1193         UnityPrintPointlessAndBail();
1194     }
1195 
1196     if (expected == actual)
1197     {
1198         return; /* Both are NULL or same pointer */
1199     }
1200 
1201     if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
1202     {
1203         UNITY_FAIL_AND_BAIL;
1204     }
1205 
1206     /* fix delta sign if need */
1207     if (in_delta < 0)
1208     {
1209         in_delta = -in_delta;
1210     }
1211 
1212     while (elements--)
1213     {
1214         current_element_delta = *ptr_expected * UNITY_DOUBLE_PRECISION;
1215 
1216         if (current_element_delta < 0)
1217         {
1218             /* fix delta sign for correct calculations */
1219             current_element_delta = -current_element_delta;
1220         }
1221 
1222         if (!UnityDoublesWithin(in_delta + current_element_delta, *ptr_expected, *ptr_actual))
1223         {
1224             UnityTestResultsFailBegin(lineNumber);
1225             UnityPrint(UnityStrElement);
1226             UnityPrintNumberUnsigned(num_elements - elements - 1);
1227             UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(*ptr_expected, *ptr_actual);
1228             UnityAddMsgIfSpecified(msg);
1229             UNITY_FAIL_AND_BAIL;
1230         }
1231         if (flags == UNITY_ARRAY_TO_ARRAY)
1232         {
1233             ptr_expected++;
1234         }
1235         ptr_actual++;
1236     }
1237 }
1238 
1239 /*-----------------------------------------------*/
UnityAssertDoublesWithin(const UNITY_DOUBLE delta,const UNITY_DOUBLE expected,const UNITY_DOUBLE actual,const char * msg,const UNITY_LINE_TYPE lineNumber)1240 void UnityAssertDoublesWithin(const UNITY_DOUBLE delta,
1241                               const UNITY_DOUBLE expected,
1242                               const UNITY_DOUBLE actual,
1243                               const char* msg,
1244                               const UNITY_LINE_TYPE lineNumber)
1245 {
1246     RETURN_IF_FAIL_OR_IGNORE;
1247 
1248     if (!UnityDoublesWithin(delta, expected, actual))
1249     {
1250         UnityTestResultsFailBegin(lineNumber);
1251         UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual);
1252         UnityAddMsgIfSpecified(msg);
1253         UNITY_FAIL_AND_BAIL;
1254     }
1255 }
1256 
1257 /*-----------------------------------------------*/
UnityAssertDoublesNotWithin(const UNITY_DOUBLE delta,const UNITY_DOUBLE expected,const UNITY_DOUBLE actual,const char * msg,const UNITY_LINE_TYPE lineNumber)1258 void UnityAssertDoublesNotWithin(const UNITY_DOUBLE delta,
1259                                  const UNITY_DOUBLE expected,
1260                                  const UNITY_DOUBLE actual,
1261                                  const char* msg,
1262                                  const UNITY_LINE_TYPE lineNumber)
1263 {
1264     RETURN_IF_FAIL_OR_IGNORE;
1265 
1266     if (UnityDoublesWithin(delta, expected, actual))
1267     {
1268         UnityTestResultsFailBegin(lineNumber);
1269         UnityPrint(UnityStrExpected);
1270         UnityPrintFloat((UNITY_DOUBLE)expected);
1271         UnityPrint(UnityStrNotEqual);
1272         UnityPrintFloat((UNITY_DOUBLE)actual);
1273         UnityAddMsgIfSpecified(msg);
1274         UNITY_FAIL_AND_BAIL;
1275     }
1276 }
1277 
1278 /*-----------------------------------------------*/
UnityAssertGreaterOrLessDouble(const UNITY_DOUBLE threshold,const UNITY_DOUBLE actual,const UNITY_COMPARISON_T compare,const char * msg,const UNITY_LINE_TYPE lineNumber)1279 void UnityAssertGreaterOrLessDouble(const UNITY_DOUBLE threshold,
1280                                     const UNITY_DOUBLE actual,
1281                                     const UNITY_COMPARISON_T compare,
1282                                     const char* msg,
1283                                     const UNITY_LINE_TYPE lineNumber)
1284 {
1285     int failed;
1286 
1287     RETURN_IF_FAIL_OR_IGNORE;
1288 
1289     failed = 0;
1290 
1291     /* Checking for "not success" rather than failure to get the right result for NaN */
1292     if (!(actual < threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; }
1293     if (!(actual > threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; }
1294 
1295     if ((compare & UNITY_EQUAL_TO) && UnityDoublesWithin(threshold * UNITY_DOUBLE_PRECISION, threshold, actual)) { failed = 0; }
1296 
1297     if (failed)
1298     {
1299         UnityTestResultsFailBegin(lineNumber);
1300         UnityPrint(UnityStrExpected);
1301         UnityPrintFloat(actual);
1302         if (compare & UNITY_GREATER_THAN) { UnityPrint(UnityStrGt); }
1303         if (compare & UNITY_SMALLER_THAN) { UnityPrint(UnityStrLt); }
1304         if (compare & UNITY_EQUAL_TO)     { UnityPrint(UnityStrOrEqual);  }
1305         UnityPrintFloat(threshold);
1306         UnityAddMsgIfSpecified(msg);
1307         UNITY_FAIL_AND_BAIL;
1308     }
1309 }
1310 
1311 /*-----------------------------------------------*/
UnityAssertDoubleSpecial(const UNITY_DOUBLE actual,const char * msg,const UNITY_LINE_TYPE lineNumber,const UNITY_FLOAT_TRAIT_T style)1312 void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual,
1313                               const char* msg,
1314                               const UNITY_LINE_TYPE lineNumber,
1315                               const UNITY_FLOAT_TRAIT_T style)
1316 {
1317     const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet};
1318     UNITY_INT should_be_trait = ((UNITY_INT)style & 1);
1319     UNITY_INT is_trait        = !should_be_trait;
1320     UNITY_INT trait_index     = (UNITY_INT)(style >> 1);
1321 
1322     RETURN_IF_FAIL_OR_IGNORE;
1323 
1324     switch (style)
1325     {
1326         case UNITY_FLOAT_IS_INF:
1327         case UNITY_FLOAT_IS_NOT_INF:
1328             is_trait = UNITY_IS_INF(actual) && (actual > 0);
1329             break;
1330         case UNITY_FLOAT_IS_NEG_INF:
1331         case UNITY_FLOAT_IS_NOT_NEG_INF:
1332             is_trait = UNITY_IS_INF(actual) && (actual < 0);
1333             break;
1334 
1335         case UNITY_FLOAT_IS_NAN:
1336         case UNITY_FLOAT_IS_NOT_NAN:
1337             is_trait = UNITY_IS_NAN(actual) ? 1 : 0;
1338             break;
1339 
1340         case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */
1341         case UNITY_FLOAT_IS_NOT_DET:
1342             is_trait = !UNITY_IS_INF(actual) && !UNITY_IS_NAN(actual);
1343             break;
1344 
1345         case UNITY_FLOAT_INVALID_TRAIT:  /* Supress warning */
1346         default: /* including UNITY_FLOAT_INVALID_TRAIT */
1347             trait_index = 0;
1348             trait_names[0] = UnityStrInvalidFloatTrait;
1349             break;
1350     }
1351 
1352     if (is_trait != should_be_trait)
1353     {
1354         UnityTestResultsFailBegin(lineNumber);
1355         UnityPrint(UnityStrExpected);
1356         if (!should_be_trait)
1357         {
1358             UnityPrint(UnityStrNot);
1359         }
1360         UnityPrint(trait_names[trait_index]);
1361         UnityPrint(UnityStrWas);
1362 #ifndef UNITY_EXCLUDE_FLOAT_PRINT
1363         UnityPrintFloat(actual);
1364 #else
1365         if (should_be_trait)
1366         {
1367             UnityPrint(UnityStrNot);
1368         }
1369         UnityPrint(trait_names[trait_index]);
1370 #endif
1371         UnityAddMsgIfSpecified(msg);
1372         UNITY_FAIL_AND_BAIL;
1373     }
1374 }
1375 
1376 #endif /* not UNITY_EXCLUDE_DOUBLE */
1377 
1378 /*-----------------------------------------------*/
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)1379 void UnityAssertNumbersWithin(const UNITY_UINT delta,
1380                               const UNITY_INT expected,
1381                               const UNITY_INT actual,
1382                               const char* msg,
1383                               const UNITY_LINE_TYPE lineNumber,
1384                               const UNITY_DISPLAY_STYLE_T style)
1385 {
1386     RETURN_IF_FAIL_OR_IGNORE;
1387 
1388     if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
1389     {
1390         if (actual > expected)
1391         {
1392             Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta);
1393         }
1394         else
1395         {
1396             Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta);
1397         }
1398     }
1399     else
1400     {
1401         if ((UNITY_UINT)actual > (UNITY_UINT)expected)
1402         {
1403             Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta);
1404         }
1405         else
1406         {
1407             Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta);
1408         }
1409     }
1410 
1411     if (Unity.CurrentTestFailed)
1412     {
1413         UnityTestResultsFailBegin(lineNumber);
1414         UnityPrint(UnityStrDelta);
1415         UnityPrintNumberByStyle((UNITY_INT)delta, style);
1416         UnityPrint(UnityStrExpected);
1417         UnityPrintNumberByStyle(expected, style);
1418         UnityPrint(UnityStrWas);
1419         UnityPrintNumberByStyle(actual, style);
1420         UnityAddMsgIfSpecified(msg);
1421         UNITY_FAIL_AND_BAIL;
1422     }
1423 }
1424 
1425 /*-----------------------------------------------*/
UnityAssertNumbersArrayWithin(const UNITY_UINT delta,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)1426 void UnityAssertNumbersArrayWithin(const UNITY_UINT delta,
1427                                    UNITY_INTERNAL_PTR expected,
1428                                    UNITY_INTERNAL_PTR actual,
1429                                    const UNITY_UINT32 num_elements,
1430                                    const char* msg,
1431                                    const UNITY_LINE_TYPE lineNumber,
1432                                    const UNITY_DISPLAY_STYLE_T style,
1433                                    const UNITY_FLAGS_T flags)
1434 {
1435     UNITY_UINT32 elements = num_elements;
1436     unsigned int length   = style & 0xF;
1437     unsigned int increment = 0;
1438 
1439     RETURN_IF_FAIL_OR_IGNORE;
1440 
1441     if (num_elements == 0)
1442     {
1443 #ifdef UNITY_COMPARE_PTRS_ON_ZERO_ARRAY
1444         UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, lineNumber, msg);
1445 #else
1446         UnityPrintPointlessAndBail();
1447 #endif
1448     }
1449 
1450     if (expected == actual)
1451     {
1452         return; /* Both are NULL or same pointer */
1453     }
1454 
1455     if (UnityIsOneArrayNull(expected, actual, lineNumber, msg))
1456     {
1457         UNITY_FAIL_AND_BAIL;
1458     }
1459 
1460     while ((elements > 0) && (elements--))
1461     {
1462         UNITY_INT expect_val;
1463         UNITY_INT actual_val;
1464 
1465         switch (length)
1466         {
1467             case 1:
1468                 /* fixing problems with signed overflow on unsigned numbers */
1469                 if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
1470                 {
1471                     expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected;
1472                     actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual;
1473                     increment  = sizeof(UNITY_INT8);
1474                 }
1475                 else
1476                 {
1477                     expect_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT8*)expected;
1478                     actual_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT8*)actual;
1479                     increment  = sizeof(UNITY_UINT8);
1480                 }
1481                 break;
1482 
1483             case 2:
1484                 /* fixing problems with signed overflow on unsigned numbers */
1485                 if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
1486                 {
1487                     expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected;
1488                     actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual;
1489                     increment  = sizeof(UNITY_INT16);
1490                 }
1491                 else
1492                 {
1493                     expect_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT16*)expected;
1494                     actual_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT16*)actual;
1495                     increment  = sizeof(UNITY_UINT16);
1496                 }
1497                 break;
1498 
1499 #ifdef UNITY_SUPPORT_64
1500             case 8:
1501                 /* fixing problems with signed overflow on unsigned numbers */
1502                 if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
1503                 {
1504                     expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected;
1505                     actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual;
1506                     increment  = sizeof(UNITY_INT64);
1507                 }
1508                 else
1509                 {
1510                     expect_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT64*)expected;
1511                     actual_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT64*)actual;
1512                     increment  = sizeof(UNITY_UINT64);
1513                 }
1514                 break;
1515 #endif
1516 
1517             default: /* default is length 4 bytes */
1518             case 4:
1519                 /* fixing problems with signed overflow on unsigned numbers */
1520                 if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
1521                 {
1522                     expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected;
1523                     actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual;
1524                     increment  = sizeof(UNITY_INT32);
1525                 }
1526                 else
1527                 {
1528                     expect_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT32*)expected;
1529                     actual_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT32*)actual;
1530                     increment  = sizeof(UNITY_UINT32);
1531                 }
1532                 length = 4;
1533                 break;
1534         }
1535 
1536         if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
1537         {
1538             if (actual_val > expect_val)
1539             {
1540                 Unity.CurrentTestFailed = (((UNITY_UINT)actual_val - (UNITY_UINT)expect_val) > delta);
1541             }
1542             else
1543             {
1544                 Unity.CurrentTestFailed = (((UNITY_UINT)expect_val - (UNITY_UINT)actual_val) > delta);
1545             }
1546         }
1547         else
1548         {
1549             if ((UNITY_UINT)actual_val > (UNITY_UINT)expect_val)
1550             {
1551                 Unity.CurrentTestFailed = (((UNITY_UINT)actual_val - (UNITY_UINT)expect_val) > delta);
1552             }
1553             else
1554             {
1555                 Unity.CurrentTestFailed = (((UNITY_UINT)expect_val - (UNITY_UINT)actual_val) > delta);
1556             }
1557         }
1558 
1559         if (Unity.CurrentTestFailed)
1560         {
1561             if ((style & UNITY_DISPLAY_RANGE_UINT) && (length < (UNITY_INT_WIDTH / 8)))
1562             {   /* For UINT, remove sign extension (padding 1's) from signed type casts above */
1563                 UNITY_INT mask = 1;
1564                 mask = (mask << 8 * length) - 1;
1565                 expect_val &= mask;
1566                 actual_val &= mask;
1567             }
1568             UnityTestResultsFailBegin(lineNumber);
1569             UnityPrint(UnityStrDelta);
1570             UnityPrintNumberByStyle((UNITY_INT)delta, style);
1571             UnityPrint(UnityStrElement);
1572             UnityPrintNumberUnsigned(num_elements - elements - 1);
1573             UnityPrint(UnityStrExpected);
1574             UnityPrintNumberByStyle(expect_val, style);
1575             UnityPrint(UnityStrWas);
1576             UnityPrintNumberByStyle(actual_val, style);
1577             UnityAddMsgIfSpecified(msg);
1578             UNITY_FAIL_AND_BAIL;
1579         }
1580         /* Walk through array by incrementing the pointers */
1581         if (flags == UNITY_ARRAY_TO_ARRAY)
1582         {
1583             expected = (UNITY_INTERNAL_PTR)((const char*)expected + increment);
1584         }
1585         actual = (UNITY_INTERNAL_PTR)((const char*)actual + increment);
1586     }
1587 }
1588 
1589 /*-----------------------------------------------*/
UnityAssertEqualString(const char * expected,const char * actual,const char * msg,const UNITY_LINE_TYPE lineNumber)1590 void UnityAssertEqualString(const char* expected,
1591                             const char* actual,
1592                             const char* msg,
1593                             const UNITY_LINE_TYPE lineNumber)
1594 {
1595     UNITY_UINT32 i;
1596 
1597     RETURN_IF_FAIL_OR_IGNORE;
1598 
1599     /* if both pointers not null compare the strings */
1600     if (expected && actual)
1601     {
1602         for (i = 0; expected[i] || actual[i]; i++)
1603         {
1604             if (expected[i] != actual[i])
1605             {
1606                 Unity.CurrentTestFailed = 1;
1607                 break;
1608             }
1609         }
1610     }
1611     else
1612     { /* fail if either null but not if both */
1613         if (expected || actual)
1614         {
1615             Unity.CurrentTestFailed = 1;
1616         }
1617     }
1618 
1619     if (Unity.CurrentTestFailed)
1620     {
1621         UnityTestResultsFailBegin(lineNumber);
1622         UnityPrintExpectedAndActualStrings(expected, actual);
1623         UnityAddMsgIfSpecified(msg);
1624         UNITY_FAIL_AND_BAIL;
1625     }
1626 }
1627 
1628 /*-----------------------------------------------*/
UnityAssertEqualStringLen(const char * expected,const char * actual,const UNITY_UINT32 length,const char * msg,const UNITY_LINE_TYPE lineNumber)1629 void UnityAssertEqualStringLen(const char* expected,
1630                                const char* actual,
1631                                const UNITY_UINT32 length,
1632                                const char* msg,
1633                                const UNITY_LINE_TYPE lineNumber)
1634 {
1635     UNITY_UINT32 i;
1636 
1637     RETURN_IF_FAIL_OR_IGNORE;
1638 
1639     /* if both pointers not null compare the strings */
1640     if (expected && actual)
1641     {
1642         for (i = 0; (i < length) && (expected[i] || actual[i]); i++)
1643         {
1644             if (expected[i] != actual[i])
1645             {
1646                 Unity.CurrentTestFailed = 1;
1647                 break;
1648             }
1649         }
1650     }
1651     else
1652     { /* fail if either null but not if both */
1653         if (expected || actual)
1654         {
1655             Unity.CurrentTestFailed = 1;
1656         }
1657     }
1658 
1659     if (Unity.CurrentTestFailed)
1660     {
1661         UnityTestResultsFailBegin(lineNumber);
1662         UnityPrintExpectedAndActualStringsLen(expected, actual, length);
1663         UnityAddMsgIfSpecified(msg);
1664         UNITY_FAIL_AND_BAIL;
1665     }
1666 }
1667 
1668 /*-----------------------------------------------*/
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)1669 void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
1670                                  const char** actual,
1671                                  const UNITY_UINT32 num_elements,
1672                                  const char* msg,
1673                                  const UNITY_LINE_TYPE lineNumber,
1674                                  const UNITY_FLAGS_T flags)
1675 {
1676     UNITY_UINT32 i = 0;
1677     UNITY_UINT32 j = 0;
1678     const char* expd = NULL;
1679     const char* act = NULL;
1680 
1681     RETURN_IF_FAIL_OR_IGNORE;
1682 
1683     /* if no elements, it's an error */
1684     if (num_elements == 0)
1685     {
1686 #ifdef UNITY_COMPARE_PTRS_ON_ZERO_ARRAY
1687         UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, lineNumber, msg);
1688 #else
1689         UnityPrintPointlessAndBail();
1690 #endif
1691     }
1692 
1693     if ((const void*)expected == (const void*)actual)
1694     {
1695         return; /* Both are NULL or same pointer */
1696     }
1697 
1698     if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg))
1699     {
1700         UNITY_FAIL_AND_BAIL;
1701     }
1702 
1703     if (flags != UNITY_ARRAY_TO_ARRAY)
1704     {
1705         expd = (const char*)expected;
1706     }
1707 
1708     do
1709     {
1710         act = actual[j];
1711         if (flags == UNITY_ARRAY_TO_ARRAY)
1712         {
1713             expd = ((const char* const*)expected)[j];
1714         }
1715 
1716         /* if both pointers not null compare the strings */
1717         if (expd && act)
1718         {
1719             for (i = 0; expd[i] || act[i]; i++)
1720             {
1721                 if (expd[i] != act[i])
1722                 {
1723                     Unity.CurrentTestFailed = 1;
1724                     break;
1725                 }
1726             }
1727         }
1728         else
1729         { /* handle case of one pointers being null (if both null, test should pass) */
1730             if (expd != act)
1731             {
1732                 Unity.CurrentTestFailed = 1;
1733             }
1734         }
1735 
1736         if (Unity.CurrentTestFailed)
1737         {
1738             UnityTestResultsFailBegin(lineNumber);
1739             if (num_elements > 1)
1740             {
1741                 UnityPrint(UnityStrElement);
1742                 UnityPrintNumberUnsigned(j);
1743             }
1744             UnityPrintExpectedAndActualStrings(expd, act);
1745             UnityAddMsgIfSpecified(msg);
1746             UNITY_FAIL_AND_BAIL;
1747         }
1748     } while (++j < num_elements);
1749 }
1750 
1751 /*-----------------------------------------------*/
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)1752 void UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected,
1753                             UNITY_INTERNAL_PTR actual,
1754                             const UNITY_UINT32 length,
1755                             const UNITY_UINT32 num_elements,
1756                             const char* msg,
1757                             const UNITY_LINE_TYPE lineNumber,
1758                             const UNITY_FLAGS_T flags)
1759 {
1760     UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected;
1761     UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual;
1762     UNITY_UINT32 elements = num_elements;
1763     UNITY_UINT32 bytes;
1764 
1765     RETURN_IF_FAIL_OR_IGNORE;
1766 
1767     if (elements == 0)
1768     {
1769 #ifdef UNITY_COMPARE_PTRS_ON_ZERO_ARRAY
1770         UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, lineNumber, msg);
1771 #else
1772         UnityPrintPointlessAndBail();
1773 #endif
1774     }
1775     if (length == 0)
1776     {
1777         UnityPrintPointlessAndBail();
1778     }
1779 
1780     if (expected == actual)
1781     {
1782         return; /* Both are NULL or same pointer */
1783     }
1784 
1785     if (UnityIsOneArrayNull(expected, actual, lineNumber, msg))
1786     {
1787         UNITY_FAIL_AND_BAIL;
1788     }
1789 
1790     while (elements--)
1791     {
1792         bytes = length;
1793         while (bytes--)
1794         {
1795             if (*ptr_exp != *ptr_act)
1796             {
1797                 UnityTestResultsFailBegin(lineNumber);
1798                 UnityPrint(UnityStrMemory);
1799                 if (num_elements > 1)
1800                 {
1801                     UnityPrint(UnityStrElement);
1802                     UnityPrintNumberUnsigned(num_elements - elements - 1);
1803                 }
1804                 UnityPrint(UnityStrByte);
1805                 UnityPrintNumberUnsigned(length - bytes - 1);
1806                 UnityPrint(UnityStrExpected);
1807                 UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8);
1808                 UnityPrint(UnityStrWas);
1809                 UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8);
1810                 UnityAddMsgIfSpecified(msg);
1811                 UNITY_FAIL_AND_BAIL;
1812             }
1813             ptr_exp++;
1814             ptr_act++;
1815         }
1816         if (flags == UNITY_ARRAY_TO_VAL)
1817         {
1818             ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected;
1819         }
1820     }
1821 }
1822 
1823 /*-----------------------------------------------*/
1824 
1825 static union
1826 {
1827     UNITY_INT8 i8;
1828     UNITY_INT16 i16;
1829     UNITY_INT32 i32;
1830 #ifdef UNITY_SUPPORT_64
1831     UNITY_INT64 i64;
1832 #endif
1833 #ifndef UNITY_EXCLUDE_FLOAT
1834     float f;
1835 #endif
1836 #ifndef UNITY_EXCLUDE_DOUBLE
1837     double d;
1838 #endif
1839 } UnityQuickCompare;
1840 
UnityNumToPtr(const UNITY_INT num,const UNITY_UINT8 size)1841 UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size)
1842 {
1843     switch(size)
1844     {
1845         case 1:
1846             UnityQuickCompare.i8 = (UNITY_INT8)num;
1847             return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i8);
1848 
1849         case 2:
1850             UnityQuickCompare.i16 = (UNITY_INT16)num;
1851             return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i16);
1852 
1853 #ifdef UNITY_SUPPORT_64
1854         case 8:
1855             UnityQuickCompare.i64 = (UNITY_INT64)num;
1856             return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i64);
1857 #endif
1858 
1859         default: /* 4 bytes */
1860             UnityQuickCompare.i32 = (UNITY_INT32)num;
1861             return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i32);
1862     }
1863 }
1864 
1865 #ifndef UNITY_EXCLUDE_FLOAT
1866 /*-----------------------------------------------*/
UnityFloatToPtr(const float num)1867 UNITY_INTERNAL_PTR UnityFloatToPtr(const float num)
1868 {
1869     UnityQuickCompare.f = num;
1870     return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.f);
1871 }
1872 #endif
1873 
1874 #ifndef UNITY_EXCLUDE_DOUBLE
1875 /*-----------------------------------------------*/
UnityDoubleToPtr(const double num)1876 UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num)
1877 {
1878     UnityQuickCompare.d = num;
1879     return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.d);
1880 }
1881 #endif
1882 
1883 #ifdef UNITY_INCLUDE_PRINT_FORMATTED
1884 
1885 /*-----------------------------------------------
1886  * printf length modifier helpers
1887  *-----------------------------------------------*/
1888 
1889 enum UnityLengthModifier {
1890     UNITY_LENGTH_MODIFIER_NONE,
1891     UNITY_LENGTH_MODIFIER_LONG_LONG,
1892     UNITY_LENGTH_MODIFIER_LONG,
1893 };
1894 
1895 #define UNITY_EXTRACT_ARG(NUMBER_T, NUMBER, LENGTH_MOD, VA, ARG_T) \
1896 do {                                                               \
1897     switch (LENGTH_MOD)                                            \
1898     {                                                              \
1899         case UNITY_LENGTH_MODIFIER_LONG_LONG:                      \
1900         {                                                          \
1901             NUMBER = (NUMBER_T)va_arg(VA, long long ARG_T);        \
1902             break;                                                 \
1903         }                                                          \
1904         case UNITY_LENGTH_MODIFIER_LONG:                           \
1905         {                                                          \
1906             NUMBER = (NUMBER_T)va_arg(VA, long ARG_T);             \
1907             break;                                                 \
1908         }                                                          \
1909         case UNITY_LENGTH_MODIFIER_NONE:                           \
1910         default:                                                   \
1911         {                                                          \
1912             NUMBER = (NUMBER_T)va_arg(VA, ARG_T);                  \
1913             break;                                                 \
1914         }                                                          \
1915     }                                                              \
1916 } while (0)
1917 
UnityLengthModifierGet(const char * pch,int * length)1918 static enum UnityLengthModifier UnityLengthModifierGet(const char *pch, int *length)
1919 {
1920     enum UnityLengthModifier length_mod;
1921     switch (pch[0])
1922     {
1923         case 'l':
1924             {
1925                 if (pch[1] == 'l')
1926                 {
1927                     *length = 2;
1928                     length_mod = UNITY_LENGTH_MODIFIER_LONG_LONG;
1929                 }
1930                 else
1931                 {
1932                     *length = 1;
1933                     length_mod = UNITY_LENGTH_MODIFIER_LONG;
1934                 }
1935                 break;
1936             }
1937         case 'h':
1938             {
1939                 // short and char are converted to int
1940                 length_mod = UNITY_LENGTH_MODIFIER_NONE;
1941                 if (pch[1] == 'h')
1942                 {
1943                     *length = 2;
1944                 }
1945                 else
1946                 {
1947                     *length = 1;
1948                 }
1949                 break;
1950             }
1951         case 'j':
1952         case 'z':
1953         case 't':
1954         case 'L':
1955             {
1956                 // Not supported, but should gobble up the length specifier anyway
1957                 length_mod = UNITY_LENGTH_MODIFIER_NONE;
1958                 *length = 1;
1959                 break;
1960             }
1961         default:
1962             {
1963                 length_mod = UNITY_LENGTH_MODIFIER_NONE;
1964                 *length = 0;
1965             }
1966     }
1967     return length_mod;
1968 }
1969 
1970 /*-----------------------------------------------
1971  * printf helper function
1972  *-----------------------------------------------*/
UnityPrintFVA(const char * format,va_list va)1973 static void UnityPrintFVA(const char* format, va_list va)
1974 {
1975     const char* pch = format;
1976     if (pch != NULL)
1977     {
1978         while (*pch)
1979         {
1980             /* format identification character */
1981             if (*pch == '%')
1982             {
1983                 pch++;
1984 
1985                 if (pch != NULL)
1986                 {
1987                     int length_mod_size;
1988                     enum UnityLengthModifier length_mod = UnityLengthModifierGet(pch, &length_mod_size);
1989                     pch += length_mod_size;
1990 
1991                     switch (*pch)
1992                     {
1993                         case 'd':
1994                         case 'i':
1995                             {
1996                                 UNITY_INT number;
1997                                 UNITY_EXTRACT_ARG(UNITY_INT, number, length_mod, va, int);
1998                                 UnityPrintNumber((UNITY_INT)number);
1999                                 break;
2000                             }
2001 #ifndef UNITY_EXCLUDE_FLOAT_PRINT
2002                         case 'f':
2003                         case 'g':
2004                             {
2005                                 const double number = va_arg(va, double);
2006                                 UnityPrintFloat((UNITY_DOUBLE)number);
2007                                 break;
2008                             }
2009 #endif
2010                         case 'u':
2011                             {
2012                                 UNITY_UINT number;
2013                                 UNITY_EXTRACT_ARG(UNITY_UINT, number, length_mod, va, unsigned int);
2014                                 UnityPrintNumberUnsigned(number);
2015                                 break;
2016                             }
2017                         case 'b':
2018                             {
2019                                 UNITY_UINT number;
2020                                 UNITY_EXTRACT_ARG(UNITY_UINT, number, length_mod, va, unsigned int);
2021                                 const UNITY_UINT mask = (UNITY_UINT)0 - (UNITY_UINT)1;
2022                                 UNITY_OUTPUT_CHAR('0');
2023                                 UNITY_OUTPUT_CHAR('b');
2024                                 UnityPrintMask(mask, number);
2025                                 break;
2026                             }
2027                         case 'x':
2028                         case 'X':
2029                             {
2030                                 UNITY_UINT number;
2031                                 UNITY_EXTRACT_ARG(UNITY_UINT, number, length_mod, va, unsigned int);
2032                                 UNITY_OUTPUT_CHAR('0');
2033                                 UNITY_OUTPUT_CHAR('x');
2034                                 UnityPrintNumberHex(number, UNITY_MAX_NIBBLES);
2035                                 break;
2036                             }
2037                         case 'p':
2038                             {
2039                                 UNITY_UINT number;
2040                                 char nibbles_to_print = 8;
2041                                 if (UNITY_POINTER_WIDTH == 64)
2042                                 {
2043                                     length_mod = UNITY_LENGTH_MODIFIER_LONG_LONG;
2044                                     nibbles_to_print = 16;
2045                                 }
2046                                 UNITY_EXTRACT_ARG(UNITY_UINT, number, length_mod, va, unsigned int);
2047                                 UNITY_OUTPUT_CHAR('0');
2048                                 UNITY_OUTPUT_CHAR('x');
2049                                 UnityPrintNumberHex((UNITY_UINT)number, nibbles_to_print);
2050                                 break;
2051                             }
2052                         case 'c':
2053                             {
2054                                 const int ch = va_arg(va, int);
2055                                 UnityPrintChar((const char *)&ch);
2056                                 break;
2057                             }
2058                         case 's':
2059                             {
2060                                 const char * string = va_arg(va, const char *);
2061                                 UnityPrint(string);
2062                                 break;
2063                             }
2064                         case '%':
2065                             {
2066                                 UnityPrintChar(pch);
2067                                 break;
2068                             }
2069                         default:
2070                             {
2071                                 /* print the unknown format character */
2072                                 UNITY_OUTPUT_CHAR('%');
2073                                 UnityPrintChar(pch);
2074                                 break;
2075                             }
2076                     }
2077                 }
2078             }
2079 #ifdef UNITY_OUTPUT_COLOR
2080             /* print ANSI escape code */
2081             else if ((*pch == 27) && (*(pch + 1) == '['))
2082             {
2083                 pch += UnityPrintAnsiEscapeString(pch);
2084                 continue;
2085             }
2086 #endif
2087             else if (*pch == '\n')
2088             {
2089                 UNITY_PRINT_EOL();
2090             }
2091             else
2092             {
2093                 UnityPrintChar(pch);
2094             }
2095 
2096             pch++;
2097         }
2098     }
2099 }
2100 
UnityPrintF(const UNITY_LINE_TYPE line,const char * format,...)2101 void UnityPrintF(const UNITY_LINE_TYPE line, const char* format, ...)
2102 {
2103     UnityTestResultsBegin(Unity.TestFile, line);
2104     UnityPrint("INFO");
2105     if(format != NULL)
2106     {
2107         UnityPrint(": ");
2108         va_list va;
2109         va_start(va, format);
2110         UnityPrintFVA(format, va);
2111         va_end(va);
2112     }
2113     UNITY_PRINT_EOL();
2114 }
2115 #endif /* ! UNITY_INCLUDE_PRINT_FORMATTED */
2116 
2117 
2118 /*-----------------------------------------------
2119  * Control Functions
2120  *-----------------------------------------------*/
2121 
2122 /*-----------------------------------------------*/
UnityFail(const char * msg,const UNITY_LINE_TYPE line)2123 void UnityFail(const char* msg, const UNITY_LINE_TYPE line)
2124 {
2125     RETURN_IF_FAIL_OR_IGNORE;
2126 
2127     UnityTestResultsBegin(Unity.TestFile, line);
2128     UnityPrint(UnityStrFail);
2129     if (msg != NULL)
2130     {
2131         UNITY_OUTPUT_CHAR(':');
2132 
2133 #ifdef UNITY_PRINT_TEST_CONTEXT
2134         UNITY_PRINT_TEST_CONTEXT();
2135 #endif
2136 #ifndef UNITY_EXCLUDE_DETAILS
2137         if (Unity.CurrentDetail1)
2138         {
2139             UnityPrint(UnityStrDetail1Name);
2140             UnityPrint(Unity.CurrentDetail1);
2141             if (Unity.CurrentDetail2)
2142             {
2143                 UnityPrint(UnityStrDetail2Name);
2144                 UnityPrint(Unity.CurrentDetail2);
2145             }
2146             UnityPrint(UnityStrSpacer);
2147         }
2148 #endif
2149         if (msg[0] != ' ')
2150         {
2151             UNITY_OUTPUT_CHAR(' ');
2152         }
2153         UnityPrint(msg);
2154     }
2155 
2156     UNITY_FAIL_AND_BAIL;
2157 }
2158 
2159 /*-----------------------------------------------*/
UnityIgnore(const char * msg,const UNITY_LINE_TYPE line)2160 void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line)
2161 {
2162     RETURN_IF_FAIL_OR_IGNORE;
2163 
2164     UnityTestResultsBegin(Unity.TestFile, line);
2165     UnityPrint(UnityStrIgnore);
2166     if (msg != NULL)
2167     {
2168         UNITY_OUTPUT_CHAR(':');
2169         UNITY_OUTPUT_CHAR(' ');
2170         UnityPrint(msg);
2171     }
2172     UNITY_IGNORE_AND_BAIL;
2173 }
2174 
2175 /*-----------------------------------------------*/
UnityMessage(const char * msg,const UNITY_LINE_TYPE line)2176 void UnityMessage(const char* msg, const UNITY_LINE_TYPE line)
2177 {
2178     UnityTestResultsBegin(Unity.TestFile, line);
2179     UnityPrint("INFO");
2180     if (msg != NULL)
2181     {
2182       UNITY_OUTPUT_CHAR(':');
2183       UNITY_OUTPUT_CHAR(' ');
2184       UnityPrint(msg);
2185     }
2186     UNITY_PRINT_EOL();
2187 }
2188 
2189 /*-----------------------------------------------*/
2190 /* If we have not defined our own test runner, then include our default test runner to make life easier */
2191 #ifndef UNITY_SKIP_DEFAULT_RUNNER
UnityDefaultTestRun(UnityTestFunction Func,const char * FuncName,const int FuncLineNum)2192 void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum)
2193 {
2194     Unity.CurrentTestName = FuncName;
2195     Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum;
2196     Unity.NumberOfTests++;
2197     UNITY_CLR_DETAILS();
2198     UNITY_EXEC_TIME_START();
2199     if (TEST_PROTECT())
2200     {
2201         setUp();
2202         Func();
2203     }
2204     if (TEST_PROTECT())
2205     {
2206         tearDown();
2207     }
2208     UNITY_EXEC_TIME_STOP();
2209     UnityConcludeTest();
2210 }
2211 #endif
2212 
2213 /*-----------------------------------------------*/
UnitySetTestFile(const char * filename)2214 void UnitySetTestFile(const char* filename)
2215 {
2216     Unity.TestFile = filename;
2217 }
2218 
2219 /*-----------------------------------------------*/
UnityBegin(const char * filename)2220 void UnityBegin(const char* filename)
2221 {
2222     Unity.TestFile = filename;
2223     Unity.CurrentTestName = NULL;
2224     Unity.CurrentTestLineNumber = 0;
2225     Unity.NumberOfTests = 0;
2226     Unity.TestFailures = 0;
2227     Unity.TestIgnores = 0;
2228     Unity.CurrentTestFailed = 0;
2229     Unity.CurrentTestIgnored = 0;
2230 
2231     UNITY_CLR_DETAILS();
2232     UNITY_OUTPUT_START();
2233 }
2234 
2235 /*-----------------------------------------------*/
UnityEnd(void)2236 int UnityEnd(void)
2237 {
2238     UNITY_PRINT_EOL();
2239     UnityPrint(UnityStrBreaker);
2240     UNITY_PRINT_EOL();
2241     UnityPrintNumber((UNITY_INT)(Unity.NumberOfTests));
2242     UnityPrint(UnityStrResultsTests);
2243     UnityPrintNumber((UNITY_INT)(Unity.TestFailures));
2244     UnityPrint(UnityStrResultsFailures);
2245     UnityPrintNumber((UNITY_INT)(Unity.TestIgnores));
2246     UnityPrint(UnityStrResultsIgnored);
2247     UNITY_PRINT_EOL();
2248     if (Unity.TestFailures == 0U)
2249     {
2250         UnityPrint(UnityStrOk);
2251     }
2252     else
2253     {
2254         UnityPrint(UnityStrFail);
2255 #ifdef UNITY_DIFFERENTIATE_FINAL_FAIL
2256         UNITY_OUTPUT_CHAR('E'); UNITY_OUTPUT_CHAR('D');
2257 #endif
2258     }
2259     UNITY_PRINT_EOL();
2260     UNITY_FLUSH_CALL();
2261     UNITY_OUTPUT_COMPLETE();
2262     return (int)(Unity.TestFailures);
2263 }
2264 
2265 /*-----------------------------------------------
2266  * Command Line Argument Support
2267  *-----------------------------------------------*/
2268 #ifdef UNITY_USE_COMMAND_LINE_ARGS
2269 
2270 char* UnityOptionIncludeNamed = NULL;
2271 char* UnityOptionExcludeNamed = NULL;
2272 int UnityVerbosity            = 1;
2273 
2274 /*-----------------------------------------------*/
UnityParseOptions(int argc,char ** argv)2275 int UnityParseOptions(int argc, char** argv)
2276 {
2277     int i;
2278     UnityOptionIncludeNamed = NULL;
2279     UnityOptionExcludeNamed = NULL;
2280 
2281     for (i = 1; i < argc; i++)
2282     {
2283         if (argv[i][0] == '-')
2284         {
2285             switch (argv[i][1])
2286             {
2287                 case 'l': /* list tests */
2288                     return -1;
2289                 case 'n': /* include tests with name including this string */
2290                 case 'f': /* an alias for -n */
2291                     if (argv[i][2] == '=')
2292                     {
2293                         UnityOptionIncludeNamed = &argv[i][3];
2294                     }
2295                     else if (++i < argc)
2296                     {
2297                         UnityOptionIncludeNamed = argv[i];
2298                     }
2299                     else
2300                     {
2301                         UnityPrint("ERROR: No Test String to Include Matches For");
2302                         UNITY_PRINT_EOL();
2303                         return 1;
2304                     }
2305                     break;
2306                 case 'q': /* quiet */
2307                     UnityVerbosity = 0;
2308                     break;
2309                 case 'v': /* verbose */
2310                     UnityVerbosity = 2;
2311                     break;
2312                 case 'x': /* exclude tests with name including this string */
2313                     if (argv[i][2] == '=')
2314                     {
2315                         UnityOptionExcludeNamed = &argv[i][3];
2316                     }
2317                     else if (++i < argc)
2318                     {
2319                         UnityOptionExcludeNamed = argv[i];
2320                     }
2321                     else
2322                     {
2323                         UnityPrint("ERROR: No Test String to Exclude Matches For");
2324                         UNITY_PRINT_EOL();
2325                         return 1;
2326                     }
2327                     break;
2328                 default:
2329                     UnityPrint("ERROR: Unknown Option ");
2330                     UNITY_OUTPUT_CHAR(argv[i][1]);
2331                     UNITY_PRINT_EOL();
2332                     /* Now display help */
2333                     /* FALLTHRU */
2334                 case 'h':
2335                     UnityPrint("Options: "); UNITY_PRINT_EOL();
2336                     UnityPrint("-l        List all tests and exit"); UNITY_PRINT_EOL();
2337                     UnityPrint("-f NAME   Filter to run only tests whose name includes NAME"); UNITY_PRINT_EOL();
2338                     UnityPrint("-n NAME   (deprecated) alias of -f"); UNITY_PRINT_EOL();
2339                     UnityPrint("-h        show this Help menu"); UNITY_PRINT_EOL();
2340                     UnityPrint("-q        Quiet/decrease verbosity"); UNITY_PRINT_EOL();
2341                     UnityPrint("-v        increase Verbosity"); UNITY_PRINT_EOL();
2342                     UnityPrint("-x NAME   eXclude tests whose name includes NAME"); UNITY_PRINT_EOL();
2343                     UNITY_OUTPUT_FLUSH();
2344                     return 1;
2345             }
2346         }
2347     }
2348 
2349     return 0;
2350 }
2351 
2352 /*-----------------------------------------------*/
IsStringInBiggerString(const char * longstring,const char * shortstring)2353 int IsStringInBiggerString(const char* longstring, const char* shortstring)
2354 {
2355     const char* lptr = longstring;
2356     const char* sptr = shortstring;
2357     const char* lnext = lptr;
2358 
2359     if (*sptr == '*')
2360     {
2361         return 1;
2362     }
2363 
2364     while (*lptr)
2365     {
2366         lnext = lptr + 1;
2367 
2368         /* If they current bytes match, go on to the next bytes */
2369         while (*lptr && *sptr && (*lptr == *sptr))
2370         {
2371             lptr++;
2372             sptr++;
2373 
2374             /* We're done if we match the entire string or up to a wildcard */
2375             if (*sptr == '*')
2376                 return 1;
2377             if (*sptr == ',')
2378                 return 1;
2379             if (*sptr == '"')
2380                 return 1;
2381             if (*sptr == '\'')
2382                 return 1;
2383             if (*sptr == ':')
2384                 return 2;
2385             if (*sptr == 0)
2386                 return 1;
2387         }
2388 
2389         /* Otherwise we start in the long pointer 1 character further and try again */
2390         lptr = lnext;
2391         sptr = shortstring;
2392     }
2393 
2394     return 0;
2395 }
2396 
2397 /*-----------------------------------------------*/
UnityStringArgumentMatches(const char * str)2398 int UnityStringArgumentMatches(const char* str)
2399 {
2400     int retval;
2401     const char* ptr1;
2402     const char* ptr2;
2403     const char* ptrf;
2404 
2405     /* Go through the options and get the substrings for matching one at a time */
2406     ptr1 = str;
2407     while (ptr1[0] != 0)
2408     {
2409         if ((ptr1[0] == '"') || (ptr1[0] == '\''))
2410         {
2411             ptr1++;
2412         }
2413 
2414         /* look for the start of the next partial */
2415         ptr2 = ptr1;
2416         ptrf = 0;
2417         do
2418         {
2419             ptr2++;
2420             if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ','))
2421             {
2422                 ptrf = &ptr2[1];
2423             }
2424         } while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ','));
2425 
2426         while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ',')))
2427         {
2428             ptr2++;
2429         }
2430 
2431         /* done if complete filename match */
2432         retval = IsStringInBiggerString(Unity.TestFile, ptr1);
2433         if (retval == 1)
2434         {
2435             return retval;
2436         }
2437 
2438         /* done if testname match after filename partial match */
2439         if ((retval == 2) && (ptrf != 0))
2440         {
2441             if (IsStringInBiggerString(Unity.CurrentTestName, ptrf))
2442             {
2443                 return 1;
2444             }
2445         }
2446 
2447         /* done if complete testname match */
2448         if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1)
2449         {
2450             return 1;
2451         }
2452 
2453         ptr1 = ptr2;
2454     }
2455 
2456     /* we couldn't find a match for any substrings */
2457     return 0;
2458 }
2459 
2460 /*-----------------------------------------------*/
UnityTestMatches(void)2461 int UnityTestMatches(void)
2462 {
2463     /* Check if this test name matches the included test pattern */
2464     int retval;
2465     if (UnityOptionIncludeNamed)
2466     {
2467         retval = UnityStringArgumentMatches(UnityOptionIncludeNamed);
2468     }
2469     else
2470     {
2471         retval = 1;
2472     }
2473 
2474     /* Check if this test name matches the excluded test pattern */
2475     if (UnityOptionExcludeNamed)
2476     {
2477         if (UnityStringArgumentMatches(UnityOptionExcludeNamed))
2478         {
2479             retval = 0;
2480         }
2481     }
2482 
2483     return retval;
2484 }
2485 
2486 #endif /* UNITY_USE_COMMAND_LINE_ARGS */
2487 /*-----------------------------------------------*/
2488 #endif /*LV_BUILD_TEST*/
2489 
2490