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