vendor/unity/src/unity.c in ceedling-0.28.1 vs vendor/unity/src/unity.c in ceedling-0.28.2
- old
+ new
@@ -25,10 +25,12 @@
static const char UnityStrIgnore[] = "IGNORE";
static const char UnityStrNull[] = "NULL";
static const char UnityStrSpacer[] = ". ";
static const char UnityStrExpected[] = " Expected ";
static const char UnityStrWas[] = " Was ";
+static const char UnityStrGt[] = " to be greater than ";
+static const char UnityStrLt[] = " to be less than ";
static const char UnityStrElement[] = " Element ";
static const char UnityStrByte[] = " Byte ";
static const char UnityStrMemory[] = " Memory Mismatch.";
static const char UnityStrDelta[] = " Values Not Within Delta ";
static const char UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless.";
@@ -233,99 +235,101 @@
}
}
/*-----------------------------------------------*/
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
-static void UnityPrintDecimalAndNumberWithLeadingZeros(UNITY_INT32 fraction_part, UNITY_INT32 divisor)
-{
- UNITY_OUTPUT_CHAR('.');
- while (divisor > 0)
- {
- UNITY_OUTPUT_CHAR('0' + fraction_part / divisor);
- fraction_part %= divisor;
- divisor /= 10;
- if (fraction_part == 0) break; /* Truncate trailing 0's */
- }
-}
-#ifndef UNITY_ROUND_TIES_AWAY_FROM_ZERO
-/* If rounds up && remainder 0.5 && result odd && below cutoff for double precision issues */
- #define ROUND_TIES_TO_EVEN(orig, num_int, num) \
- if (num_int > (num) && (num) - (num_int-1) <= 0.5 && (num_int & 1) == 1 && orig < 1e22) \
- num_int -= 1 /* => a tie to round down to even */
-#else
- #define ROUND_TIES_TO_EVEN(orig, num_int, num) /* Remove macro */
-#endif
-
-/* Printing floating point numbers is hard. Some goals of this implementation: works for embedded
- * systems, floats or doubles, and has a reasonable format. The key paper in this area,
- * 'How to Print Floating-Point Numbers Accurately' by Steele & White, shows an approximation by
- * scaling called Dragon 2. This code uses a similar idea. The other core algorithm uses casts and
- * floating subtraction to give exact remainders after the decimal, to be scaled into an integer.
- * Extra trailing 0's are excluded. The output defaults to rounding to nearest, ties to even. You
- * can enable rounding ties away from zero. Note: UNITY_DOUBLE param can typedef to float or double
-
- * The old version required compiling in snprintf. For reference, with a similar format as now:
- * char buf[19];
- * if (number > 4294967296.0 || -number > 4294967296.0) snprintf(buf, sizeof buf, "%.8e", number);
- * else snprintf(buf, sizeof buf, "%.6f", number);
- * UnityPrint(buf);
- */
+/* This function prints a floating-point value in a format similar to
+ * printf("%.6g"). It can work with either single- or double-precision,
+ * but for simplicity, it prints only 6 significant digits in either case.
+ * Printing more than 6 digits accurately is hard (at least in the single-
+ * precision case) and isn't attempted here. */
void UnityPrintFloat(const UNITY_DOUBLE input_number)
{
- UNITY_DOUBLE number;
+ UNITY_DOUBLE number = input_number;
- if (input_number < 0)
+ /* print minus sign (including for negative zero) */
+ if (number < 0.0f || (number == 0.0f && 1.0f / number < 0.0f))
{
UNITY_OUTPUT_CHAR('-');
- number = -input_number;
- } else
- {
- number = input_number;
+ number = -number;
}
- if (isnan(number)) UnityPrint(UnityStrNaN);
- else if (isinf(number)) UnityPrintLen(UnityStrInf, 3);
- else if (number <= 0.0000005 && number > 0) UnityPrint("0.000000..."); /* Small number */
- else if (number < 4294967295.9999995) /* Rounded result fits in 32 bits, "%.6f" format */
+ /* handle zero, NaN, and +/- infinity */
+ if (number == 0.0f) UnityPrint("0");
+ else if (isnan(number)) UnityPrint("nan");
+ else if (isinf(number)) UnityPrint("inf");
+ else
{
- const UNITY_INT32 divisor = 1000000/10;
- UNITY_UINT32 integer_part = (UNITY_UINT32)number;
- UNITY_INT32 fraction_part = (UNITY_INT32)((number - (UNITY_DOUBLE)integer_part)*1000000.0 + 0.5);
- /* Double precision calculation gives best performance for six rounded decimal places */
- ROUND_TIES_TO_EVEN(number, fraction_part, (number - (UNITY_DOUBLE)integer_part)*1000000.0);
+ int exponent = 0;
+ int decimals, digits;
+ UNITY_INT32 n;
+ char buf[16];
- if (fraction_part == 1000000) /* Carry across the decimal point */
+ /* scale up or down by powers of 10 */
+ while (number < 100000.0f / 1e6f) { number *= 1e6f; exponent -= 6; }
+ while (number < 100000.0f) { number *= 10.0f; exponent--; }
+ while (number > 1000000.0f * 1e6f) { number /= 1e6f; exponent += 6; }
+ while (number > 1000000.0f) { number /= 10.0f; exponent++; }
+
+ /* round to nearest integer */
+ n = ((UNITY_INT32)(number + number) + 1) / 2;
+ if (n > 999999)
{
- fraction_part = 0;
- integer_part += 1;
+ n = 100000;
+ exponent++;
}
- UnityPrintNumberUnsigned(integer_part);
- UnityPrintDecimalAndNumberWithLeadingZeros(fraction_part, divisor);
- }
- else /* Number is larger, use exponential format of 9 digits, "%.8e" */
- {
- const UNITY_INT32 divisor = 1000000000/10;
- UNITY_INT32 integer_part;
- UNITY_DOUBLE_TYPE divide = 10.0;
- int exponent = 9;
+ /* determine where to place decimal point */
+ decimals = (exponent <= 0 && exponent >= -9) ? -exponent : 5;
+ exponent += decimals;
- while (number / divide >= 1000000000.0 - 0.5)
+ /* truncate trailing zeroes after decimal point */
+ while (decimals > 0 && n % 10 == 0)
{
- divide *= 10;
- exponent++;
+ n /= 10;
+ decimals--;
}
- integer_part = (UNITY_INT32)(number / divide + 0.5);
- /* Double precision calculation required for float, to produce 9 rounded digits */
- ROUND_TIES_TO_EVEN(number, integer_part, number / divide);
- UNITY_OUTPUT_CHAR('0' + integer_part / divisor);
- UnityPrintDecimalAndNumberWithLeadingZeros(integer_part % divisor, divisor / 10);
- UNITY_OUTPUT_CHAR('e');
- UNITY_OUTPUT_CHAR('+');
- if (exponent < 10) UNITY_OUTPUT_CHAR('0');
- UnityPrintNumber(exponent);
+ /* build up buffer in reverse order */
+ digits = 0;
+ while (n != 0 || digits < decimals + 1)
+ {
+ buf[digits++] = (char)('0' + n % 10);
+ n /= 10;
+ }
+ while (digits > 0)
+ {
+ if(digits == decimals) UNITY_OUTPUT_CHAR('.');
+ UNITY_OUTPUT_CHAR(buf[--digits]);
+ }
+
+ /* print exponent if needed */
+ if (exponent != 0)
+ {
+ UNITY_OUTPUT_CHAR('e');
+
+ if(exponent < 0)
+ {
+ UNITY_OUTPUT_CHAR('-');
+ exponent = -exponent;
+ }
+ else
+ {
+ UNITY_OUTPUT_CHAR('+');
+ }
+
+ digits = 0;
+ while (exponent != 0 || digits < 2)
+ {
+ buf[digits++] = (char)('0' + exponent % 10);
+ exponent /= 10;
+ }
+ while (digits > 0)
+ {
+ UNITY_OUTPUT_CHAR(buf[--digits]);
+ }
+ }
}
}
#endif /* ! UNITY_EXCLUDE_FLOAT_PRINT */
/*-----------------------------------------------*/
@@ -523,9 +527,53 @@
UnityPrintNumberByStyle(actual, style);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
}
+
+/*-----------------------------------------------*/
+void UnityAssertGreaterNumber(const UNITY_INT threshold,
+ const UNITY_INT actual,
+ const char *msg,
+ const UNITY_LINE_TYPE lineNumber,
+ const UNITY_DISPLAY_STYLE_T style)
+{
+ RETURN_IF_FAIL_OR_IGNORE;
+
+ if (!(actual > threshold))
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrExpected);
+ UnityPrintNumberByStyle(actual, style);
+ UnityPrint(UnityStrGt);
+ UnityPrintNumberByStyle(threshold, style);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+}
+
+/*-----------------------------------------------*/
+void UnityAssertSmallerNumber(const UNITY_INT threshold,
+ const UNITY_INT actual,
+ const char *msg,
+ const UNITY_LINE_TYPE lineNumber,
+ const UNITY_DISPLAY_STYLE_T style)
+{
+ RETURN_IF_FAIL_OR_IGNORE;
+
+ if (!(actual < threshold))
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrExpected);
+ UnityPrintNumberByStyle(actual, style);
+ UnityPrint(UnityStrLt);
+ UnityPrintNumberByStyle(threshold, style);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+}
+
+
#define UnityPrintPointlessAndBail() \
{ \
UnityTestResultsFailBegin(lineNumber); \
UnityPrint(UnityStrPointless); \