mirror of https://github.com/ARMmbed/mbed-os.git
commit
1b206471e9
|
@ -14,7 +14,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
#include "mbed.h"
|
||||
#endif
|
||||
#include "mbed_printf.h"
|
||||
|
||||
#include "utest/utest.h"
|
||||
|
@ -88,35 +90,41 @@ static control_t test_printf_d(const size_t call_count)
|
|||
result_baseline = printf("lld: %lld\r\n", LLONG_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%jd not supported by mbed\r\n");
|
||||
|
||||
#else
|
||||
result_minimal = mbed_printf("jd: %jd\r\n", INT32_MIN);
|
||||
result_baseline = printf("jd: %jd\r\n", (intmax_t) INT32_MIN);
|
||||
TEST_ASSERT_EQUAL_INT(17, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("jd: %jd\r\n", INT32_MAX);
|
||||
result_baseline = printf("jd: %jd\r\n", (intmax_t) INT32_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(16, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%zd not supported by mbed\r\n");
|
||||
|
||||
#else
|
||||
result_minimal = mbed_printf("zd: %zd\r\n", INT32_MIN);
|
||||
result_baseline = printf("zd: %zd\r\n", (ssize_t) INT32_MIN);
|
||||
TEST_ASSERT_EQUAL_INT(17, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("zd: %zd\r\n", INT32_MAX);
|
||||
result_baseline = printf("zd: %zd\r\n", (ssize_t) INT32_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(16, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%td not supported by mbed\r\n");
|
||||
|
||||
#else
|
||||
result_minimal = mbed_printf("td: %td\r\n", PTRDIFF_MIN);
|
||||
result_baseline = printf("td: %td\r\n", PTRDIFF_MIN);
|
||||
TEST_ASSERT_EQUAL_INT(17, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("td: %td\r\n", PTRDIFF_MAX);
|
||||
result_baseline = printf("td: %td\r\n", PTRDIFF_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(16, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
return CaseNext;
|
||||
}
|
||||
|
@ -168,29 +176,41 @@ static control_t test_printf_u(const size_t call_count)
|
|||
result_baseline = printf("llu: %llu\r\n", ULLONG_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%ju not supported by mbed\r\n");
|
||||
#else
|
||||
result_minimal = mbed_printf("ju: %ju\r\n", 0);
|
||||
result_baseline = printf("ju: %ju\r\n",(uintmax_t) 0);
|
||||
TEST_ASSERT_EQUAL_INT(7, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("ju: %ju\r\n", UINTMAX_MAX);
|
||||
result_baseline = printf("ju: %ju\r\n", UINTMAX_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(7, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%zu not supported by mbed\r\n");
|
||||
#else
|
||||
result_minimal = mbed_printf("zu: %zu\r\n", 0);
|
||||
result_baseline = printf("zu: %zu\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_INT(7, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("zu: %zu\r\n", SIZE_MAX);
|
||||
result_baseline = printf("zu: %zu\r\n", SIZE_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(16, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%tu not supported by mbed\r\n");
|
||||
#else
|
||||
result_minimal = mbed_printf("tu: %tu\r\n", 0);
|
||||
result_baseline = printf("tu: %tu\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_INT(7, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("tu: %tu\r\n", UINTPTR_MAX);
|
||||
result_baseline = printf("tu: %tu\r\n", UINTPTR_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(26, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
return CaseNext;
|
||||
}
|
||||
|
@ -202,11 +222,9 @@ static control_t test_printf_x(const size_t call_count)
|
|||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
printf("%%x always prints even characters\r\n");
|
||||
|
||||
result_minimal = mbed_printf("hhX: %hhX\r\n", 0);
|
||||
result_baseline = printf("hhX: %hhX\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_INT(9, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("hhX: %hhX\r\n", UCHAR_MAX);
|
||||
result_baseline = printf("hhX: %hhX\r\n", UCHAR_MAX);
|
||||
|
@ -214,7 +232,7 @@ static control_t test_printf_x(const size_t call_count)
|
|||
|
||||
result_minimal = mbed_printf("hX: %hX\r\n", 0);
|
||||
result_baseline = printf("hX: %hX\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("hX: %hX\r\n", USHRT_MAX);
|
||||
result_baseline = printf("hX: %hX\r\n", USHRT_MAX);
|
||||
|
@ -222,7 +240,7 @@ static control_t test_printf_x(const size_t call_count)
|
|||
|
||||
result_minimal = mbed_printf("X: %X\r\n", 0);
|
||||
result_baseline = printf("X: %X\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_INT(7, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("X: %X\r\n", UINT_MAX);
|
||||
result_baseline = printf("X: %X\r\n", UINT_MAX);
|
||||
|
@ -230,7 +248,7 @@ static control_t test_printf_x(const size_t call_count)
|
|||
|
||||
result_minimal = mbed_printf("lX: %lX\r\n", 0);
|
||||
result_baseline = printf("lX: %lX\r\n", 0UL);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("lX: %lX\r\n", ULONG_MAX);
|
||||
result_baseline = printf("lX: %lX\r\n", ULONG_MAX);
|
||||
|
@ -238,35 +256,47 @@ static control_t test_printf_x(const size_t call_count)
|
|||
|
||||
result_minimal = mbed_printf("llX: %llX\r\n", 0);
|
||||
result_baseline = printf("llX: %llX\r\n", 0ULL);
|
||||
TEST_ASSERT_EQUAL_INT(9, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("llX: %llX\r\n", ULLONG_MAX);
|
||||
result_baseline = printf("llX: %llX\r\n", ULLONG_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%jX not supported by mbed\r\n");
|
||||
#else
|
||||
result_minimal = mbed_printf("jX: %jX\r\n", 0);
|
||||
result_baseline = printf("jX: %jX\r\n", (uintmax_t) 0);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("jX: %jX\r\n", UINTMAX_MAX);
|
||||
result_baseline = printf("jX: %jX\r\n", UINTMAX_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%zX not supported by mbed\r\n");
|
||||
#else
|
||||
result_minimal = mbed_printf("zX: %zX\r\n", 0);
|
||||
result_baseline = printf("zX: %zX\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("zX: %zX\r\n", SIZE_MAX);
|
||||
result_baseline = printf("zX: %zX\r\n", SIZE_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(14, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%tX not supported by mbed\r\n");
|
||||
#else
|
||||
result_minimal = mbed_printf("tX: %tX\r\n", 0);
|
||||
result_baseline = printf("tX: %tX\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("tX: %tX\r\n", UINTPTR_MAX);
|
||||
result_baseline = printf("tX: %tX\r\n", UINTPTR_MAX);
|
||||
TEST_ASSERT_EQUAL_INT(22, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
return CaseNext;
|
||||
}
|
||||
|
@ -336,41 +366,47 @@ static control_t test_snprintf_d(const size_t call_count)
|
|||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%jd not supported by mbed\r\n");
|
||||
|
||||
#else
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "jd: %jd\r\n", INT32_MIN);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "jd: %jd\r\n", (intmax_t) INT32_MIN);
|
||||
TEST_ASSERT_EQUAL_STRING("jd: -2147483648\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(17, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "jd: %jd\r\n", INT32_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "jd: %jd\r\n", (intmax_t) INT32_MAX);
|
||||
TEST_ASSERT_EQUAL_STRING("jd: 2147483647\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(16, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%zd not supported by mbed\r\n");
|
||||
|
||||
#else
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "zd: %zd\r\n", INT32_MIN);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "zd: %zd\r\n", (ssize_t) INT32_MIN);
|
||||
TEST_ASSERT_EQUAL_STRING("zd: -2147483648\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(17, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "zd: %zd\r\n", INT32_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "zd: %zd\r\n", (ssize_t) INT32_MAX);
|
||||
TEST_ASSERT_EQUAL_STRING("zd: 2147483647\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(16, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%td not supported by mbed\r\n");
|
||||
|
||||
#else
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "td: %td\r\n", PTRDIFF_MIN);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "td: %td\r\n", PTRDIFF_MIN);
|
||||
TEST_ASSERT_EQUAL_STRING("td: -2147483648\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(17, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "td: %td\r\n", PTRDIFF_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "td: %td\r\n", PTRDIFF_MAX);
|
||||
TEST_ASSERT_EQUAL_STRING("td: 2147483647\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(16, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
return CaseNext;
|
||||
}
|
||||
|
@ -434,35 +470,47 @@ static control_t test_snprintf_u(const size_t call_count)
|
|||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%ju not supported by mbed\r\n");
|
||||
#else
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "ju: %ju\r\n", 0);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "ju: %ju\r\n", (uintmax_t) 0);
|
||||
TEST_ASSERT_EQUAL_STRING("ju: 0\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(7, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "ju: %ju\r\n", UINTMAX_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "ju: %ju\r\n", UINTMAX_MAX);
|
||||
TEST_ASSERT_EQUAL_STRING("ju: 0\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(7, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%zu not supported by mbed\r\n");
|
||||
#else
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "zu: %zu\r\n", 0);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "zu: %zu\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_STRING("zu: 0\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(7, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "zu: %zu\r\n", SIZE_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "zu: %zu\r\n", SIZE_MAX);
|
||||
TEST_ASSERT_EQUAL_STRING("zu: 4294967295\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(16, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%tu not supported by mbed\r\n");
|
||||
#else
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "tu: %tu\r\n", 0);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "tu: %tu\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_STRING("tu: 0\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(7, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "tu: %tu\r\n", UINTPTR_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "tu: %tu\r\n", UINTPTR_MAX);
|
||||
TEST_ASSERT_EQUAL_STRING("tu: 18446744073709551615\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(26, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
return CaseNext;
|
||||
}
|
||||
|
@ -476,12 +524,10 @@ static control_t test_snprintf_x(const size_t call_count)
|
|||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
printf("%%x always prints even characters\r\n");
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hhX: %hhX\r\n", 0);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hhX: %hhX\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_STRING("hhX: 00\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(9, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hhX: %hhX\r\n", UCHAR_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hhX: %hhX\r\n", UCHAR_MAX);
|
||||
|
@ -490,8 +536,8 @@ static control_t test_snprintf_x(const size_t call_count)
|
|||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hX: %hX\r\n", 0);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hX: %hX\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_STRING("hX: 00\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hX: %hX\r\n", USHRT_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hX: %hX\r\n", USHRT_MAX);
|
||||
|
@ -499,8 +545,8 @@ static control_t test_snprintf_x(const size_t call_count)
|
|||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "X: %X\r\n", 0);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "X: %X\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_STRING("X: 00\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(7, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "X: %X\r\n", UINT_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "X: %X\r\n", UINT_MAX);
|
||||
|
@ -509,8 +555,8 @@ static control_t test_snprintf_x(const size_t call_count)
|
|||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "lX: %lX\r\n", 0);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "lX: %lX\r\n", 0UL);
|
||||
TEST_ASSERT_EQUAL_STRING("lX: 00\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "lX: %lX\r\n", ULONG_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "lX: %lX\r\n", ULONG_MAX);
|
||||
|
@ -519,47 +565,60 @@ static control_t test_snprintf_x(const size_t call_count)
|
|||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "llX: %llX\r\n", 0);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "llX: %llX\r\n", 0ULL);
|
||||
TEST_ASSERT_EQUAL_STRING("llX: 00\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(9, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "llX: %llX\r\n", ULLONG_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "llX: %llX\r\n", ULLONG_MAX);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%jX not supported by mbed\r\n");
|
||||
#else
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "jX: %jX\r\n", 0);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "jX: %jX\r\n", (uintmax_t) 0);
|
||||
TEST_ASSERT_EQUAL_STRING("jX: 00\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "jX: %jX\r\n", UINTMAX_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "jX: %jX\r\n", UINTMAX_MAX);
|
||||
TEST_ASSERT_EQUAL_STRING("jX: 00\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%xX not supported by mbed\r\n");
|
||||
#else
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "zX: %zX\r\n", 0);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "zX: %zX\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_STRING("zX: 00\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "zX: %zX\r\n", SIZE_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "zX: %zX\r\n", SIZE_MAX);
|
||||
TEST_ASSERT_EQUAL_STRING("zX: FFFFFFFF\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(14, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LIKE_MBED
|
||||
printf("%%tX not supported by mbed\r\n");
|
||||
#else
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "tX: %tX\r\n", 0);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "tX: %tX\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_STRING("tX: 00\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "tX: %tX\r\n", UINTPTR_MAX);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "tX: %tX\r\n", UINTPTR_MAX);
|
||||
TEST_ASSERT_EQUAL_STRING("tX: FFFFFFFFFFFFFFFF\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(22, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
#endif
|
||||
|
||||
return CaseNext;
|
||||
}
|
||||
|
||||
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
|
||||
static control_t test_printf_f(const size_t call_count)
|
||||
{
|
||||
int result_baseline;
|
||||
|
@ -576,7 +635,7 @@ static control_t test_printf_f(const size_t call_count)
|
|||
|
||||
result_minimal = mbed_printf("f: %f\r\n", 0);
|
||||
result_baseline = printf("f: %f\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_printf("f: %f\r\n", pi);
|
||||
result_baseline = printf("f: %f\r\n", pi);
|
||||
|
@ -604,8 +663,8 @@ static control_t test_snprintf_f(const size_t call_count)
|
|||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %f\r\n", 0);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "f: %f\r\n", 0);
|
||||
TEST_ASSERT_EQUAL_STRING("f: 0.0\r\n", buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(8, result_minimal);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %f\r\n", pi);
|
||||
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "f: %f\r\n", pi);
|
||||
|
@ -614,6 +673,99 @@ static control_t test_snprintf_f(const size_t call_count)
|
|||
|
||||
return CaseNext;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Generic buffer overflow test function.
|
||||
* Template parameters:
|
||||
* 'T' is the type being tested
|
||||
* 'buf_size' is the buffer size used in tests
|
||||
* Function parameters:
|
||||
* 'fmt' is the format to use for sprintf
|
||||
* 'data' is the data that will be printed
|
||||
*/
|
||||
template<typename T, size_t buf_size>
|
||||
static control_t test_snprintf_buffer_overflow_generic(const char *fmt, T data)
|
||||
{
|
||||
char buffer_baseline[buf_size];
|
||||
char buffer_minimal[buf_size];
|
||||
int result_baseline;
|
||||
int result_minimal;
|
||||
|
||||
/* empty buffer test */
|
||||
result_minimal = mbed_snprintf(buffer_minimal, 0, fmt, data);
|
||||
result_baseline = snprintf(buffer_baseline, 0, fmt, data);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
/* buffer isn't large enough, output needs to be truncated */
|
||||
result_minimal = mbed_snprintf(buffer_minimal, buf_size - 2, fmt, data);
|
||||
result_baseline = snprintf(buffer_baseline, buf_size - 2, fmt, data);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
/* buffer is one byte shorter than needed, string terminator must
|
||||
be written and output must be truncated */
|
||||
result_minimal = mbed_snprintf(buffer_minimal, buf_size - 1, fmt, data);
|
||||
result_baseline = snprintf(buffer_baseline, buf_size - 1, fmt, data);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
/* buffer is just long enough */
|
||||
result_minimal = mbed_snprintf(buffer_minimal, buf_size, fmt, data);
|
||||
result_baseline = snprintf(buffer_baseline, buf_size, fmt, data);
|
||||
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
|
||||
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
|
||||
|
||||
return CaseNext;
|
||||
}
|
||||
|
||||
/* Based on the generic buffer overflow function above, create tests for
|
||||
each relevant data type. In each case, the buffer for printing will only
|
||||
be large enough to fit the printed data. */
|
||||
static control_t test_snprintf_buffer_overflow_d(const size_t call_count)
|
||||
{
|
||||
return test_snprintf_buffer_overflow_generic<int, sizeof("d: -1024")>("d: %d", -1024);
|
||||
}
|
||||
|
||||
static control_t test_snprintf_buffer_overflow_ld(const size_t call_count)
|
||||
{
|
||||
return test_snprintf_buffer_overflow_generic<long, sizeof("ld: -1048576")>("ld: %ld", -1048576L);
|
||||
}
|
||||
|
||||
static control_t test_snprintf_buffer_overflow_lld(const size_t call_count)
|
||||
{
|
||||
return test_snprintf_buffer_overflow_generic<long long, sizeof("lld: -1099511627776")>("lld: %lld", -1099511627776LL);
|
||||
}
|
||||
|
||||
static control_t test_snprintf_buffer_overflow_u(const size_t call_count)
|
||||
{
|
||||
return test_snprintf_buffer_overflow_generic<unsigned int, sizeof("u: 1024")>("u: %u", 1024);
|
||||
}
|
||||
|
||||
static control_t test_snprintf_buffer_overflow_lu(const size_t call_count)
|
||||
{
|
||||
return test_snprintf_buffer_overflow_generic<unsigned long, sizeof("lu: 1048576")>("lu: %lu", 1048576UL);
|
||||
}
|
||||
|
||||
static control_t test_snprintf_buffer_overflow_llu(const size_t call_count)
|
||||
{
|
||||
return test_snprintf_buffer_overflow_generic<unsigned long long, sizeof("llu: 1099511627776")>("llu: %llu", 1099511627776ULL);
|
||||
}
|
||||
|
||||
static control_t test_snprintf_buffer_overflow_x(const size_t call_count)
|
||||
{
|
||||
return test_snprintf_buffer_overflow_generic<unsigned int, sizeof("x: 0x400")>("x: 0x%x", 0x400);
|
||||
}
|
||||
|
||||
static control_t test_snprintf_buffer_overflow_lx(const size_t call_count)
|
||||
{
|
||||
return test_snprintf_buffer_overflow_generic<unsigned long, sizeof("lx: 0x100000")>("lx: 0x%lx", 0x100000UL);
|
||||
}
|
||||
|
||||
static control_t test_snprintf_buffer_overflow_llx(const size_t call_count)
|
||||
{
|
||||
return test_snprintf_buffer_overflow_generic<unsigned long long, sizeof("llx: 0x10000000000")>("llx: 0x%llx", 0x10000000000ULL);
|
||||
}
|
||||
|
||||
utest::v1::status_t greentea_setup(const size_t number_of_cases)
|
||||
{
|
||||
|
@ -632,6 +784,15 @@ Case cases[] = {
|
|||
Case("printf %f", test_printf_f),
|
||||
Case("snprintf %f", test_snprintf_f),
|
||||
#endif
|
||||
Case("snprintf buffer overflow %d", test_snprintf_buffer_overflow_d),
|
||||
Case("snprintf buffer overflow %ld", test_snprintf_buffer_overflow_ld),
|
||||
Case("snprintf buffer overflow %lld", test_snprintf_buffer_overflow_lld),
|
||||
Case("snprintf buffer overflow %u", test_snprintf_buffer_overflow_u),
|
||||
Case("snprintf buffer overflow %lu", test_snprintf_buffer_overflow_lu),
|
||||
Case("snprintf buffer overflow %llu", test_snprintf_buffer_overflow_llu),
|
||||
Case("snprintf buffer overflow %x", test_snprintf_buffer_overflow_x),
|
||||
Case("snprintf buffer overflow %lx", test_snprintf_buffer_overflow_lx),
|
||||
Case("snprintf buffer overflow %llx", test_snprintf_buffer_overflow_llx),
|
||||
};
|
||||
|
||||
Specification specification(greentea_setup, cases, greentea_test_teardown_handler);
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/***************************/
|
||||
/* MBED */
|
||||
|
@ -131,6 +133,37 @@ static void mbed_minimal_formatted_string_void_pointer(char* buffer, size_t leng
|
|||
static void mbed_minimal_formatted_string_character(char* buffer, size_t length, int* result, char character);
|
||||
static void mbed_minimal_formatted_string_string(char* buffer, size_t length, int* result, const char* string);
|
||||
|
||||
/**
|
||||
* @brief Print a single character, checking for buffer and size overflows.
|
||||
*
|
||||
* @param buffer The buffer to store output (NULL for stdout).
|
||||
* @param[in] length The length of the buffer.
|
||||
* @param result The current output location.
|
||||
* @param[in] data The char to be printed.
|
||||
*/
|
||||
static void mbed_minimal_putchar(char *buffer, size_t length, int* result, char data)
|
||||
{
|
||||
/* only continue if 'result' doesn't overflow */
|
||||
if ((*result >= 0) && (*result <= INT_MAX - 1))
|
||||
{
|
||||
/* write data only if there's enough space */
|
||||
if ((size_t)*result < length)
|
||||
{
|
||||
if (buffer)
|
||||
{
|
||||
buffer[*result] = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
MBED_PRINT_CHARACTER(data);
|
||||
}
|
||||
}
|
||||
/* increment 'result' even if data was not written. This ensures that
|
||||
'mbed_minimal_formatted_string' returns the correct value. */
|
||||
*result += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Print signed integer.
|
||||
*
|
||||
|
@ -141,26 +174,13 @@ static void mbed_minimal_formatted_string_string(char* buffer, size_t length, in
|
|||
*/
|
||||
static void mbed_minimal_formatted_string_signed(char* buffer, size_t length, int* result, MBED_SIGNED_STORAGE value)
|
||||
{
|
||||
/* only continue if buffer can fit at least 1 character and if
|
||||
'result' doesn't overflow */
|
||||
if ((*result >= 0) && (*result <= INT_MAX - 1) && ((size_t)*result + 1 <= length))
|
||||
{
|
||||
MBED_UNSIGNED_STORAGE new_value = 0;
|
||||
|
||||
/* if value is negative print sign and treat as positive number */
|
||||
if (value < 0)
|
||||
{
|
||||
/* write sign */
|
||||
if (buffer)
|
||||
{
|
||||
buffer[*result] = '-';
|
||||
}
|
||||
else
|
||||
{
|
||||
MBED_PRINT_CHARACTER('-');
|
||||
}
|
||||
|
||||
*result += 1;
|
||||
mbed_minimal_putchar(buffer, length, result, '-');
|
||||
|
||||
/* get absolute value using two's complement */
|
||||
new_value = ~((MBED_UNSIGNED_STORAGE) value) + 1;
|
||||
|
@ -172,7 +192,6 @@ static void mbed_minimal_formatted_string_signed(char* buffer, size_t length, in
|
|||
|
||||
/* use unsigned long int function */
|
||||
mbed_minimal_formatted_string_unsigned(buffer, length, result, new_value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,23 +204,10 @@ static void mbed_minimal_formatted_string_signed(char* buffer, size_t length, in
|
|||
*/
|
||||
static void mbed_minimal_formatted_string_unsigned(char* buffer, size_t length, int* result, MBED_UNSIGNED_STORAGE value)
|
||||
{
|
||||
/* only continue if buffer can fit at least 1 character and if
|
||||
'result' doesn't overflow */
|
||||
if ((*result >= 0) && (*result <= INT_MAX - 1) && ((size_t)*result + 1 <= length))
|
||||
{
|
||||
/* treat 0 as a corner case */
|
||||
if (value == 0)
|
||||
{
|
||||
if (buffer)
|
||||
{
|
||||
buffer[*result] = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
MBED_PRINT_CHARACTER('0');
|
||||
}
|
||||
|
||||
*result += 1;
|
||||
mbed_minimal_putchar(buffer, length, result, '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -221,19 +227,9 @@ static void mbed_minimal_formatted_string_unsigned(char* buffer, size_t length,
|
|||
}
|
||||
|
||||
/* write scratch pad to buffer or output */
|
||||
for ( ; (*result <= INT_MAX- 1) && ((size_t)*result < length) && (index > 0); index--)
|
||||
for ( ; index > 0; index--)
|
||||
{
|
||||
if (buffer)
|
||||
{
|
||||
buffer[*result] = scratch[index - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
MBED_PRINT_CHARACTER(scratch[index - 1]);
|
||||
}
|
||||
|
||||
*result += 1;
|
||||
}
|
||||
mbed_minimal_putchar(buffer, length, result, scratch[index - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -250,9 +246,7 @@ static void mbed_minimal_formatted_string_hexadecimal(char* buffer, size_t lengt
|
|||
{
|
||||
bool print_leading_zero = false;
|
||||
|
||||
/* only continue each loop if buffer can fit at least 2 characters
|
||||
and if 'result' doesn't overflow */
|
||||
for (int index = 7; (*result >= 0) && (*result <= INT_MAX - 2) && ((size_t)*result + 2 <= length) && (index >= 0); index--)
|
||||
for (int index = 7; index >= 0; index--)
|
||||
{
|
||||
/* get most significant byte */
|
||||
uint8_t output = value >> (8 * index);
|
||||
|
@ -260,28 +254,19 @@ static void mbed_minimal_formatted_string_hexadecimal(char* buffer, size_t lengt
|
|||
/* only print leading zeros when set */
|
||||
if (print_leading_zero || (output != 0) || (index == 0))
|
||||
{
|
||||
/* print zeroes after the first non-zero byte */
|
||||
print_leading_zero = true;
|
||||
|
||||
unsigned int nibble_one = (output >> 4);
|
||||
unsigned int nibble_two = (output & 0x0F);
|
||||
|
||||
const char int2hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
|
||||
/* write to buffer or stdout */
|
||||
if (buffer)
|
||||
{
|
||||
buffer[*result] = int2hex[nibble_one];
|
||||
buffer[*result + 1] = int2hex[nibble_two];
|
||||
}
|
||||
else
|
||||
{
|
||||
MBED_PRINT_CHARACTER(int2hex[nibble_one]);
|
||||
MBED_PRINT_CHARACTER(int2hex[nibble_two]);
|
||||
if (print_leading_zero || nibble_one != 0) {
|
||||
mbed_minimal_putchar(buffer, length, result, int2hex[nibble_one]);
|
||||
}
|
||||
mbed_minimal_putchar(buffer, length, result, int2hex[nibble_two]);
|
||||
|
||||
*result += 2;
|
||||
/* print zeroes after the first non-zero byte */
|
||||
print_leading_zero = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -296,28 +281,12 @@ static void mbed_minimal_formatted_string_hexadecimal(char* buffer, size_t lengt
|
|||
*/
|
||||
static void mbed_minimal_formatted_string_void_pointer(char* buffer, size_t length, int* result, const void* value)
|
||||
{
|
||||
/* only continue if buffer can fit '0x' and twice the size of a void*
|
||||
and if 'result' doesn't overflow */
|
||||
size_t needed = 2 + 2 * sizeof(void*);
|
||||
if ((*result >= 0) && ((size_t)*result <= INT_MAX - needed) && ((size_t)*result + needed <= length))
|
||||
{
|
||||
/* write leading 0x */
|
||||
if (buffer)
|
||||
{
|
||||
buffer[*result] = '0';
|
||||
buffer[*result + 1] = 'x';
|
||||
}
|
||||
else
|
||||
{
|
||||
MBED_PRINT_CHARACTER('0');
|
||||
MBED_PRINT_CHARACTER('x');
|
||||
}
|
||||
|
||||
*result += 2;
|
||||
mbed_minimal_putchar(buffer, length, result, '0');
|
||||
mbed_minimal_putchar(buffer, length, result, 'x');
|
||||
|
||||
/* write rest as a regular hexadecimal number */
|
||||
mbed_minimal_formatted_string_hexadecimal(buffer, length, result, (ptrdiff_t) value);
|
||||
}
|
||||
}
|
||||
|
||||
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
|
||||
|
@ -331,10 +300,6 @@ static void mbed_minimal_formatted_string_void_pointer(char* buffer, size_t leng
|
|||
*/
|
||||
static void mbed_minimal_formatted_string_double(char* buffer, size_t length, int* result, double value)
|
||||
{
|
||||
/* only continue if buffer can fit at least 1 character and if
|
||||
'result' doesn't overflow */
|
||||
if ((*result >= 0) && (*result <= INT_MAX - 1) && ((size_t)*result + 1 <= length))
|
||||
{
|
||||
/* get integer part */
|
||||
MBED_SIGNED_STORAGE integer = value;
|
||||
|
||||
|
@ -377,7 +342,6 @@ static void mbed_minimal_formatted_string_double(char* buffer, size_t length, in
|
|||
|
||||
/* write decimal part */
|
||||
mbed_minimal_formatted_string_unsigned(buffer, length, result, decimal);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -391,14 +355,10 @@ static void mbed_minimal_formatted_string_double(char* buffer, size_t length, in
|
|||
*/
|
||||
static void mbed_minimal_formatted_string_character(char* buffer, size_t length, int* result, char character)
|
||||
{
|
||||
/* only continue if the buffer can fit 1 character and if
|
||||
'result' doesn't overflow */
|
||||
if ((*result >= 0) && (*result <= INT_MAX - 1) && ((size_t)*result + 1 <= length))
|
||||
{
|
||||
/* write character */
|
||||
if (buffer)
|
||||
{
|
||||
buffer[*result] = character;
|
||||
mbed_minimal_putchar(buffer, length, result, character);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -406,19 +366,13 @@ static void mbed_minimal_formatted_string_character(char* buffer, size_t length,
|
|||
#if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES
|
||||
if (character == '\n' && mbed_stdio_out_prev != '\r')
|
||||
{
|
||||
MBED_PRINT_CHARACTER('\r');
|
||||
*result += 1;
|
||||
mbed_minimal_putchar(buffer, length, result, '\r');
|
||||
}
|
||||
|
||||
/* cache character */
|
||||
mbed_stdio_out_prev = character;
|
||||
#endif
|
||||
|
||||
/* write character to stdout */
|
||||
MBED_PRINT_CHARACTER(character);
|
||||
}
|
||||
|
||||
*result += 1;
|
||||
mbed_minimal_putchar(buffer, length, result, character);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,44 +386,10 @@ static void mbed_minimal_formatted_string_character(char* buffer, size_t length,
|
|||
*/
|
||||
static void mbed_minimal_formatted_string_string(char* buffer, size_t length, int* result, const char* string)
|
||||
{
|
||||
/* only continue if the buffer can fit at least 1 character and if
|
||||
'result' doesn't overflow */
|
||||
if ((*result >= 0) && (*result <= INT_MAX - 1) && ((size_t)*result + 1 <= length))
|
||||
while (*string != '\0')
|
||||
{
|
||||
/* count characters in string */
|
||||
size_t remaining = length - *result;
|
||||
size_t string_length = 0;
|
||||
|
||||
/* only count characters that will fit into buffer */
|
||||
while ((string[string_length] != '\0') && (string_length < remaining))
|
||||
{
|
||||
string_length++;
|
||||
}
|
||||
|
||||
/* copy string to buffer */
|
||||
if (buffer)
|
||||
{
|
||||
/* ensure that the value of "result" doesn't overflow */
|
||||
if (string_length + *result > INT_MAX)
|
||||
{
|
||||
string_length = (size_t)INT_MAX - *result;
|
||||
}
|
||||
for (size_t index = 0; index < string_length; index++)
|
||||
{
|
||||
buffer[*result + index] = string[index];
|
||||
}
|
||||
}
|
||||
/* print string */
|
||||
else
|
||||
{
|
||||
for (size_t index = 0; index < string_length; index++)
|
||||
{
|
||||
MBED_PRINT_CHARACTER(string[index]);
|
||||
}
|
||||
}
|
||||
|
||||
/* add length to counter */
|
||||
*result += string_length;
|
||||
mbed_minimal_putchar(buffer, length, result, *string);
|
||||
string ++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,12 +409,23 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
|
|||
MBED_INITIALIZE_PRINT();
|
||||
|
||||
int result = 0;
|
||||
bool empty_buffer = false;
|
||||
|
||||
/* ensure that function wasn't called with an empty buffer, or with or with
|
||||
a buffer size that is larger than the maximum 'int' value, or with
|
||||
a NULL format specifier */
|
||||
if (format && length > 0 && length <= INT_MAX)
|
||||
if (format && length >= 0 && length <= INT_MAX)
|
||||
{
|
||||
/* Make sure that there's always space for the NULL terminator */
|
||||
if (length > 0)
|
||||
{
|
||||
length --;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the buffer is empty, there's no place to write the terminator */
|
||||
empty_buffer = true;
|
||||
}
|
||||
/* parse string */
|
||||
for (size_t index = 0; format[index] != '\0'; index++)
|
||||
{
|
||||
|
@ -756,11 +687,19 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
|
|||
}
|
||||
}
|
||||
|
||||
/* if writing to buffer, NULL terminate string in reserved space*/
|
||||
if (buffer && ((size_t)result < length))
|
||||
if (buffer && !empty_buffer)
|
||||
{
|
||||
/* NULL-terminate the buffer no matter what. We use '<=' to compare instead of '<'
|
||||
because we know that we initially reserved space for '\0' by decrementing length */
|
||||
if ((size_t)result <= length)
|
||||
{
|
||||
buffer[result] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[length] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
Loading…
Reference in New Issue