summaryrefslogtreecommitdiff
path: root/test/printf.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/printf.c')
-rw-r--r--test/printf.c706
1 files changed, 545 insertions, 161 deletions
diff --git a/test/printf.c b/test/printf.c
index f7e9b9dd2d..728aa9b4a8 100644
--- a/test/printf.c
+++ b/test/printf.c
@@ -1,4 +1,4 @@
-/* Copyright 2019 The Chromium OS Authors. All rights reserved.
+/* Copyright 2019 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -12,14 +12,31 @@
#include "test_util.h"
#include "util.h"
+#ifdef USE_BUILTIN_STDLIB
+/*
+ * When USE_BUILTIN_STDLIB is defined, we want to test the EC printf
+ * implementation. We need to include the builtin header file directly so
+ * that we can call the EC version (crec_vsnprintf) when linking with the
+ * standard library on the host.
+ */
+#include "builtin/stdio.h"
+#define VSNPRINTF crec_vsnprintf
+#define SNPRINTF crec_snprintf
+static const bool use_builtin_stdlib = true;
+#else
+#include <stdio.h>
+#define VSNPRINTF vsnprintf
+#define SNPRINTF snprintf
+static const bool use_builtin_stdlib = false;
+#endif
+
#define INIT_VALUE 0x5E
#define NO_BYTES_TOUCHED NULL
static const char err_str[] = "ERROR";
static char output[1024];
-int run(int expect_ret, const char *expect,
- bool output_null, size_t size_limit,
+int run(int expect_ret, const char *expect, bool output_null, size_t size_limit,
const char *format, va_list args)
{
size_t expect_size = expect ? strlen(expect) + 1 : 0;
@@ -34,10 +51,8 @@ int run(int expect_ret, const char *expect,
TEST_ASSERT(expect_size <= size_limit);
memset(output, INIT_VALUE, sizeof(output));
- rv = vsnprintf(output_null ? NULL : output, size_limit,
- format, args);
- ccprintf("received='%.*s' | ret =%d\n",
- 30, output, rv);
+ rv = VSNPRINTF(output_null ? NULL : output, size_limit, format, args);
+ ccprintf("received='%.*s' | ret =%d\n", 30, output, rv);
TEST_ASSERT_ARRAY_EQ(output, expect, expect_size);
TEST_ASSERT_MEMSET(&output[expect_size], INIT_VALUE,
@@ -59,252 +74,621 @@ int expect_success(const char *expect, const char *format, ...)
int rv;
va_start(args, format);
- rv = run(EC_SUCCESS, expect,
- false, sizeof(output),
- format, args);
+ rv = run(EC_SUCCESS, expect, false, sizeof(output), format, args);
va_end(args);
return rv;
}
-int expect(int expect_ret, const char *expect,
- bool output_null, size_t size_limit,
- const char *format, ...)
+int expect(int expect_ret, const char *expect, bool output_null,
+ size_t size_limit, const char *format, ...)
{
va_list args;
int rv;
va_start(args, format);
- rv = run(expect_ret, expect,
- output_null, size_limit,
- format, args);
+ rv = run(expect_ret, expect, output_null, size_limit, format, args);
va_end(args);
return rv;
}
-#define T(n) \
- do { \
- int rv = (n); \
- if (rv != EC_SUCCESS) \
- return rv; \
+#define T(n) \
+ do { \
+ int rv = (n); \
+ if (rv != EC_SUCCESS) \
+ return rv; \
} while (0)
test_static int test_vsnprintf_args(void)
{
- T(expect_success("", ""));
- T(expect_success("a", "a"));
-
- T(expect(/* expect an invalid args error */
- EC_ERROR_INVAL, NO_BYTES_TOUCHED,
- /* given 0 as output size limit */
- false, 0, ""));
+ T(expect_success("", ""));
+ T(expect_success("a", "a"));
+
+ if (use_builtin_stdlib) {
+ /*
+ * TODO(b/239233116): This differs from the C standard library
+ * behavior and should probably be changed.
+ */
+ T(expect(/* expect an invalid args error */
+ EC_ERROR_INVAL, NO_BYTES_TOUCHED,
+ /* given 0 as output size limit */
+ false, 0, ""));
+ T(expect(/* expect an overflow error */
+ EC_ERROR_OVERFLOW, "",
+ /* given 1 as output size limit with a non-blank format
+ */
+ false, 1, "a"));
+ T(expect(/* expect an invalid args error */
+ EC_ERROR_INVAL, NO_BYTES_TOUCHED,
+ /* given NULL as the output buffer */
+ true, sizeof(output), ""));
+ T(expect(/* expect an invalid args error */
+ EC_ERROR_INVAL, NO_BYTES_TOUCHED,
+ /* given a NULL format string */
+ false, sizeof(output), NULL));
+ }
T(expect(/* expect SUCCESS */
EC_SUCCESS, "",
/* given 1 as output size limit and a blank format */
false, 1, ""));
- T(expect(/* expect an overflow error */
- EC_ERROR_OVERFLOW, "",
- /* given 1 as output size limit with a non-blank format */
- false, 1, "a"));
-
- T(expect(/* expect an invalid args error */
- EC_ERROR_INVAL, NO_BYTES_TOUCHED,
- /* given NULL as the output buffer */
- true, sizeof(output), ""));
- T(expect(/* expect an invalid args error */
- EC_ERROR_INVAL, NO_BYTES_TOUCHED,
- /* given a NULL format string */
- false, sizeof(output), NULL));
return EC_SUCCESS;
}
test_static int test_vsnprintf_int(void)
{
- T(expect_success("123", "%d", 123));
- T(expect_success("-123", "%d", -123));
- T(expect_success("+123", "%+d", 123));
- T(expect_success("-123", "%+d", -123));
- T(expect_success("123", "%-d", 123));
- T(expect_success("-123", "%-d", -123));
-
- T(expect_success(" 123", "%5d", 123));
- T(expect_success(" +123", "%+5d", 123));
- T(expect_success("00123", "%05d", 123));
- T(expect_success("00123", "%005d", 123));
- /*
- * TODO(crbug.com/974084): This odd behavior should be fixed.
- * T(expect_success("+0123", "%+05d", 123));
- * Actual: "0+123"
- * T(expect_success("+0123", "%+005d", 123));
- * Actual: "0+123"
- */
+ T(expect_success("123", "%d", 123));
+ T(expect_success("-123", "%d", -123));
+ T(expect_success("+123", "%+d", 123));
+ T(expect_success("-123", "%+d", -123));
+ T(expect_success("123", "%-d", 123));
+ T(expect_success("-123", "%-d", -123));
+
+ T(expect_success(" 123", "%5d", 123));
+ T(expect_success(" +123", "%+5d", 123));
+ T(expect_success("00123", "%05d", 123));
+ T(expect_success("00123", "%005d", 123));
+
+ if (use_builtin_stdlib) {
+ /*
+ * TODO(b/239233116): These are incorrect and should be fixed.
+ */
+ /* Fixed point. */
+ T(expect_success("0.00123", "%.5d", 123));
+ T(expect_success("12.3", "%2.1d", 123));
+ /* Precision or width larger than buffer should fail. */
+ T(expect(EC_ERROR_OVERFLOW, " 1", false, 4, "%5d", 123));
+ T(expect(EC_ERROR_OVERFLOW, " ", false, 4, "%10d", 123));
+ T(expect(EC_ERROR_OVERFLOW, "123", false, 4, "%-10d", 123));
+ T(expect(EC_ERROR_OVERFLOW, "0.0", false, 4, "%.10d", 123));
+ } else {
+ int ret;
+
+ T(expect_success("00123", "%.5d", 123));
+ T(expect_success("123", "%2.1d", 123));
+
+ /*
+ * From the man page: The functions snprintf() and vsnprintf()
+ * do not write more than size bytes (including the
+ * terminating null byte ('\0')). If the output was truncated
+ * due to this limit, then the return value is the number of
+ * characters (excluding the terminating null byte) which
+ * would have been written to the final string if enough
+ * space had been available. Thus, a return value of size or
+ * more means that the output was truncated.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-truncation"
+ ret = SNPRINTF(output, 4, "%5d", 123);
+ TEST_ASSERT_ARRAY_EQ(output, " 1", 4);
+ TEST_EQ(ret, 5, "%d");
+
+ ret = SNPRINTF(output, 4, "%10d", 123);
+ TEST_ASSERT_ARRAY_EQ(output, " ", 4);
+ TEST_EQ(ret, 10, "%d");
+
+ ret = SNPRINTF(output, 4, "%-10d", 123);
+ TEST_ASSERT_ARRAY_EQ(output, "123", 4);
+ TEST_EQ(ret, 10, "%d");
+
+ ret = SNPRINTF(output, 4, "%.10d", 123);
+ TEST_ASSERT_ARRAY_EQ(output, "000", 4);
+ TEST_EQ(ret, 10, "%d");
+#pragma GCC diagnostic pop
+ }
- T(expect_success(" 123", "%*d", 5, 123));
- T(expect_success(" +123", "%+*d", 5, 123));
- T(expect_success("00123", "%0*d", 5, 123));
- /*
- * TODO(crbug.com/974084): This odd behavior should be fixed.
- * T(expect_success("00123", "%00*d", 5, 123));
- * Actual: "ERROR"
- */
- T(expect_success("0+123", "%+0*d", 5, 123));
- /*
- * TODO(crbug.com/974084): This odd behavior should be fixed.
- * T(expect_success("0+123", "%+00*d", 5, 123));
- * Actual: "ERROR"
- */
+ if (use_builtin_stdlib) {
+ /*
+ * TODO(b/239233116): These are incorrect and should be fixed.
+ */
+ T(expect_success("0+123", "%+05d", 123));
+ T(expect_success("0+123", "%+005d", 123));
+ } else {
+ T(expect_success("+0123", "%+05d", 123));
+ T(expect_success("+0123", "%+005d", 123));
+ }
+
+ T(expect_success(" 123", "%*d", 5, 123));
+ T(expect_success(" +123", "%+*d", 5, 123));
+ T(expect_success("00123", "%0*d", 5, 123));
- T(expect_success("123 ", "%-5d", 123));
- T(expect_success("+123 ", "%-+5d", 123));
- T(expect_success(err_str, "%+-5d", 123));
- T(expect_success("123 ", "%-05d", 123));
- T(expect_success("123 ", "%-005d", 123));
- T(expect_success("+123 ", "%-+05d", 123));
- T(expect_success("+123 ", "%-+005d", 123));
-
- T(expect_success("0.00123", "%.5d", 123));
- T(expect_success("+0.00123", "%+.5d", 123));
- T(expect_success("0.00123", "%7.5d", 123));
- T(expect_success(" 0.00123", "%9.5d", 123));
- T(expect_success(" +0.00123", "%+9.5d", 123));
-
- T(expect_success("123", "%u", 123));
- T(expect_success("4294967295", "%u", -1));
+ if (use_builtin_stdlib) {
+ /*
+ * TODO(b/239233116): This incorrect and should be fixed.
+ */
+ T(expect_success(err_str, "%00*d", 5, 123));
+ } else {
+ T(expect_success("00123", "%00*d", 5, 123));
+ }
+
+ if (use_builtin_stdlib) {
+ /*
+ * TODO(b/239233116): This is incorrect and should be fixed.
+ */
+ T(expect_success("0+123", "%+0*d", 5, 123));
+ } else {
+ T(expect_success("+0123", "%+0*d", 5, 123));
+ }
+
+ if (use_builtin_stdlib) {
+ /*
+ * TODO(b/239233116): This is incorrect and should be fixed.
+ */
+ T(expect_success(err_str, "%+00*d", 5, 123));
+ } else {
+ T(expect_success("+0123", "%+00*d", 5, 123));
+ }
+
+ T(expect_success("123 ", "%-5d", 123));
+ T(expect_success("+123 ", "%-+5d", 123));
+ if (use_builtin_stdlib) {
+ /*
+ * TODO(b/239233116): This incorrect and should be fixed.
+ */
+ T(expect_success(err_str, "%+-5d", 123));
+ } else {
+ T(expect_success("+123 ", "%+-5d", 123));
+ }
+ T(expect_success("123 ", "%-05d", 123));
+ T(expect_success("123 ", "%-005d", 123));
+ T(expect_success("+123 ", "%-+05d", 123));
+ T(expect_success("+123 ", "%-+005d", 123));
+
+ if (use_builtin_stdlib) {
+ /*
+ * TODO(b/239233116): These are incorrect and should be fixed.
+ */
+ T(expect_success("0.00123", "%.5d", 123));
+ T(expect_success("+0.00123", "%+.5d", 123));
+ T(expect_success("0.00123", "%7.5d", 123));
+ T(expect_success(" 0.00123", "%9.5d", 123));
+ T(expect_success(" +0.00123", "%+9.5d", 123));
+ } else {
+ T(expect_success("00123", "%.5d", 123));
+ T(expect_success("+00123", "%+.5d", 123));
+ T(expect_success(" 00123", "%7.5d", 123));
+ T(expect_success(" 00123", "%9.5d", 123));
+ T(expect_success(" +00123", "%+9.5d", 123));
+ }
+
+ T(expect_success("123", "%u", 123));
+ T(expect_success("4294967295", "%u", -1));
T(expect_success("18446744073709551615", "%llu", (uint64_t)-1));
- T(expect_success("0", "%x", 0));
- T(expect_success("0", "%X", 0));
- T(expect_success("5e", "%x", 0X5E));
- T(expect_success("5E", "%X", 0X5E));
+ T(expect_success("0", "%x", 0));
+ T(expect_success("0", "%X", 0));
+ T(expect_success("5e", "%x", 0X5E));
+ T(expect_success("5E", "%X", 0X5E));
+
+ return EC_SUCCESS;
+}
+
+test_static int test_printf_long32_enabled(void)
+{
+ bool use_l32 = IS_ENABLED(CONFIG_PRINTF_LONG_IS_32BITS);
+
+ if (IS_ENABLED(BOARD_BLOONCHIPPER) || IS_ENABLED(BOARD_DARTMONKEY))
+ TEST_ASSERT(use_l32);
+ else
+ TEST_ASSERT(!use_l32);
+ return EC_SUCCESS;
+}
+
+test_static int test_vsnprintf_32bit_long_supported(void)
+{
+ long long_min = INT32_MIN;
+ long long_max = INT32_MAX;
+ unsigned long ulong_max = UINT32_MAX;
+ char const *long_min_str = "-2147483648";
+ char const *long_max_str = "2147483647";
+ char const *ulong_max_str = "4294967295";
+ char const *long_min_hexstr = "80000000";
+ char const *long_max_hexstr = "7fffffff";
+ char const *ulong_max_hexstr = "ffffffff";
+
+ T(expect_success(long_min_str, "%ld", long_min));
+ T(expect_success(long_min_hexstr, "%lx", long_min));
+ T(expect_success(long_max_str, "%ld", long_max));
+ T(expect_success(long_max_hexstr, "%lx", long_max));
+ T(expect_success(ulong_max_str, "%lu", ulong_max));
+ T(expect_success(ulong_max_hexstr, "%lx", ulong_max));
+ T(expect_success(long_max_str, "%ld", long_max));
+
+ T(expect_success(" +123", "%+*ld", 5, 123));
+ T(expect_success("00000123", "%08lu", 123));
+ T(expect_success("131415", "%d%lu%d", 13, 14L, 15));
/*
- * %l is deprecated on 32-bit systems (see crbug.com/984041), but is
- * is still functional on 64-bit systems.
+ * %i and %li are only supported via the CONFIG_PRINTF_LONG_IS_32BITS
+ * configuration (see https://issuetracker.google.com/issues/172210614).
*/
- if (sizeof(long) == sizeof(uint32_t)) {
- T(expect_success(err_str, "%lx", 0x7b));
- T(expect_success(err_str, "%08lu", 0x7b));
- T(expect_success("13ERROR", "%d%lu", 13, 14));
+ T(expect_success("123", "%i", 123));
+ T(expect_success("123", "%li", 123));
+
+ return EC_SUCCESS;
+}
+
+test_static int test_vsnprintf_64bit_long_supported(void)
+{
+ /* These lines are only executed when sizeof(long) is 64-bits but are
+ * still compiled by systems with 32-bit longs, so the casts are needed
+ * to avoid compilation errors.
+ */
+ long long_min = (long)INT64_MIN;
+ long long_max = (long)INT64_MAX;
+ unsigned long ulong_max = (unsigned long)UINT64_MAX;
+ char const *long_min_str = "-9223372036854775808";
+ char const *long_max_str = "9223372036854775807";
+ char const *ulong_max_str = "18446744073709551615";
+ char const *long_min_hexstr = "8000000000000000";
+ char const *long_max_hexstr = "7fffffffffffffff";
+ char const *ulong_max_hexstr = "ffffffffffffffff";
+
+ T(expect_success(long_min_str, "%ld", long_min));
+ T(expect_success(long_min_hexstr, "%lx", long_min));
+ T(expect_success(long_max_str, "%ld", long_max));
+ T(expect_success(long_max_hexstr, "%lx", long_max));
+ T(expect_success(ulong_max_str, "%lu", ulong_max));
+ T(expect_success(ulong_max_hexstr, "%lx", ulong_max));
+ T(expect_success(long_max_str, "%ld", long_max));
+
+ T(expect_success(" +123", "%+*ld", 5, 123));
+ T(expect_success("00000123", "%08lu", 123));
+ T(expect_success("131415", "%d%lu%d", 13, 14L, 15));
+
+ if (use_builtin_stdlib) {
+ /*
+ * TODO(b/239233116): These are incorrect and should be fixed.
+ */
+ T(expect_success(err_str, "%i", 123));
+ T(expect_success(err_str, "%li", 123));
} else {
- T(expect_success("7b", "%lx", 0x7b));
- T(expect_success("00000123", "%08lu", 123));
- T(expect_success("131415", "%d%lu%d", 13, 14L, 15));
+ T(expect_success("123", "%i", 123));
+ T(expect_success("123", "%li", 123));
}
return EC_SUCCESS;
}
+test_static int test_vsnprintf_long_not_supported(void)
+{
+ T(expect_success(err_str, "%ld", 0x7b));
+ T(expect_success(err_str, "%li", 0x7b));
+ T(expect_success(err_str, "%lu", 0x7b));
+ T(expect_success(err_str, "%lx", 0x7b));
+ T(expect_success(err_str, "%08lu", 123));
+ T(expect_success("13ERROR", "%d%lu%d", 13, 14L, 15));
+
+ T(expect_success(err_str, "%i", 123));
+ T(expect_success(err_str, "%li", 123));
+
+ return EC_SUCCESS;
+}
+
+test_static int test_vsnprintf_long(void)
+{
+ /*
+ * %l is functional on 64-bit systems but is not supported on 32-bit
+ * systems (see https://issuetracker.google.com/issues/172210614) unless
+ * explicitly enabled via configuration.
+ */
+ if (IS_ENABLED(CONFIG_PRINTF_LONG_IS_32BITS))
+ return test_vsnprintf_32bit_long_supported();
+ else if (sizeof(long) == sizeof(uint64_t))
+ return test_vsnprintf_64bit_long_supported();
+ else
+ return test_vsnprintf_long_not_supported();
+}
+
test_static int test_vsnprintf_pointers(void)
{
void *ptr = (void *)0x55005E00;
- unsigned int val = 0;
-
- T(expect_success("55005e00", "%pP", ptr));
- T(expect_success(err_str, "%P", ptr));
- /* %p by itself is invalid */
- T(expect(EC_ERROR_INVAL, NO_BYTES_TOUCHED,
- false, 0, "%p"));
- /* %p with an unknown suffix is invalid */
- T(expect(EC_ERROR_INVAL, NO_BYTES_TOUCHED,
- false, 0, "%p "));
- /* %p with an unknown suffix is invalid */
- T(expect(EC_ERROR_INVAL, NO_BYTES_TOUCHED,
- false, 0, "%pQ"));
-
- /* Test %pb, binary format */
- T(expect_success("0", "%pb", BINARY_VALUE(val, 0)));
- val = 0x5E;
- T(expect_success("1011110", "%pb", BINARY_VALUE(val, 0)));
- T(expect_success("0000000001011110", "%pb", BINARY_VALUE(val, 16)));
- val = 0x12345678;
- T(expect_success("10010001101000101011001111000", "%pb",
- BINARY_VALUE(val, 0)));
- val = 0xFEDCBA90;
- /* Test a number that makes the longest string possible */
- T(expect_success("11111110110111001011101010010000", "%pb",
- BINARY_VALUE(val, 0)));
+
+ if (use_builtin_stdlib) {
+ /*
+ * TODO(b/239233116): This incorrect and should be fixed.
+ */
+ T(expect_success("55005e00", "%p", ptr));
+ } else {
+ T(expect_success("0x55005e00", "%p", ptr));
+ }
+
return EC_SUCCESS;
}
test_static int test_vsnprintf_chars(void)
{
- T(expect_success("a", "%c", 'a'));
- T(expect_success("*", "%c", '*'));
+ T(expect_success("a", "%c", 'a'));
+ T(expect_success("*", "%c", '*'));
return EC_SUCCESS;
}
test_static int test_vsnprintf_strings(void)
{
- T(expect_success("abc", "%s", "abc"));
- T(expect_success(" abc", "%5s", "abc"));
- T(expect_success("abc", "%0s", "abc"));
- T(expect_success("abc ", "%-5s", "abc"));
- T(expect_success("abc", "%*s", 0, "abc"));
- T(expect_success("a", "%.1s", "abc"));
- T(expect_success("a", "%.*s", 1, "abc"));
- T(expect_success("", "%.0s", "abc"));
- T(expect_success("", "%.*s", 0, "abc"));
- /*
- * TODO(crbug.com/974084):
- * Ignoring the padding parameter is slightly
- * odd behavior and could use a review.
- */
- T(expect_success("ab", "%5.2s", "abc"));
- T(expect_success("abc", "%.4s", "abc"));
+ T(expect_success("abc", "%s", "abc"));
+ T(expect_success(" abc", "%5s", "abc"));
+ T(expect_success("abc", "%0s", "abc"));
+ T(expect_success("abc ", "%-5s", "abc"));
+ T(expect_success("abc", "%*s", 0, "abc"));
+ T(expect_success("a", "%.1s", "abc"));
+ T(expect_success("a", "%.*s", 1, "abc"));
+ T(expect_success("", "%.0s", "abc"));
+ T(expect_success("", "%.*s", 0, "abc"));
+ if (use_builtin_stdlib) {
+ /*
+ * TODO(b/239233116): This incorrect and should be fixed.
+ */
+ T(expect_success("ab", "%5.2s", "abc"));
+ } else {
+ T(expect_success(" ab", "%5.2s", "abc"));
+ }
+ T(expect_success("abc", "%.4s", "abc"));
/*
* Given a malformed string (address 0x1 is a good example),
* if we ask for zero precision, expect no bytes to be read
* from the malformed address and a blank output string.
*/
- T(expect_success("", "%.0s", (char *)1));
+ T(expect_success("", "%.0s", (char *)1));
return EC_SUCCESS;
}
-test_static int test_vsnprintf_timestamps(void)
+test_static int test_snprintf_timestamp(void)
{
+ char str[PRINTF_TIMESTAMP_BUF_SIZE];
+ int size;
+ int ret;
uint64_t ts = 0;
- T(expect_success("0.000000", "%pT", &ts));
+ /* Success cases. */
+
+ ret = snprintf_timestamp(str, sizeof(str), ts);
+ TEST_EQ(ret, 8, "%d");
+ TEST_ASSERT_ARRAY_EQ(str, "0.000000", sizeof("0.000000"));
+
ts = 123456;
- T(expect_success("0.123456", "%pT", &ts));
+ ret = snprintf_timestamp(str, sizeof(str), ts);
+ TEST_EQ(ret, 8, "%d");
+ TEST_ASSERT_ARRAY_EQ(str, "0.123456", sizeof("0.123456"));
+
ts = 9999999000000;
- T(expect_success("9999999.000000", "%pT", &ts));
+ ret = snprintf_timestamp(str, sizeof(str), ts);
+ TEST_EQ(ret, 14, "%d");
+ TEST_ASSERT_ARRAY_EQ(str, "9999999.000000", sizeof("9999999.000000"));
+
+ ts = UINT64_MAX;
+ ret = snprintf_timestamp(str, sizeof(str), ts);
+ TEST_EQ(ret, 21, "%d");
+ TEST_ASSERT_ARRAY_EQ(str, "18446744073709.551615",
+ sizeof("18446744073709.551615"));
+
+ /* Error cases. */
+
+ /* Buffer is too small by one. */
+ size = 21;
+ ts = UINT64_MAX;
+ str[0] = 'f';
+ ret = snprintf_timestamp(str, size, ts);
+ TEST_EQ(ret, -EC_ERROR_OVERFLOW, "%d");
+ TEST_EQ(str[0], '\0', "%d");
+
+ /* Size is zero. */
+ size = 0;
+ ts = UINT64_MAX;
+ str[0] = 'f';
+ ret = snprintf_timestamp(str, size, ts);
+ TEST_EQ(ret, -EC_ERROR_INVAL, "%d");
+ TEST_EQ(str[0], 'f', "%d");
+
+ /* Size is one. */
+ size = 1;
+ ts = UINT64_MAX;
+ str[0] = 'f';
+ ret = snprintf_timestamp(str, size, ts);
+ TEST_EQ(ret, -EC_ERROR_OVERFLOW, "%d");
+ TEST_EQ(str[0], '\0', "%d");
+
return EC_SUCCESS;
}
-test_static int test_vsnprintf_hexdump(void)
+test_static int test_snprintf_hex_buffer(void)
{
- const char bytes[] = {0x00, 0x5E};
+ const uint8_t bytes[] = { 0xAB, 0x5E };
+ char str_buf[5];
+ int rv;
+
+ /* Success cases. */
+
+ memset(str_buf, 0xff, sizeof(str_buf));
+ rv = snprintf_hex_buffer(str_buf, sizeof(str_buf), HEX_BUF(bytes, 2));
+ TEST_ASSERT_ARRAY_EQ(str_buf, "ab5e", sizeof("ab5e"));
+ TEST_EQ(rv, 4, "%d");
+
+ memset(str_buf, 0xff, sizeof(str_buf));
+ rv = snprintf_hex_buffer(str_buf, sizeof(str_buf), HEX_BUF(bytes, 0));
+ TEST_ASSERT_ARRAY_EQ(str_buf, "", sizeof(""));
+ TEST_EQ(rv, 0, "%d");
+
+ memset(str_buf, 0xff, sizeof(str_buf));
+ rv = snprintf_hex_buffer(str_buf, sizeof(str_buf), HEX_BUF(bytes, 1));
+ TEST_ASSERT_ARRAY_EQ(str_buf, "ab", sizeof("ab"));
+ TEST_EQ(rv, 2, "%d");
+
+ /* Error cases. */
+
+ /* Zero for buffer size argument is an error. */
+ memset(str_buf, 0xff, sizeof(str_buf));
+ TEST_ASSERT_MEMSET(str_buf, (char)0xff, sizeof(str_buf));
+ rv = snprintf_hex_buffer(str_buf, 0, HEX_BUF(bytes, 2));
+ TEST_EQ(rv, -EC_ERROR_INVAL, "%d");
+ TEST_ASSERT_MEMSET(str_buf, (char)0xff, sizeof(str_buf));
+
+ /* Buffer only has space for terminating '\0'. */
+ memset(str_buf, 0xff, sizeof(str_buf));
+ TEST_ASSERT_MEMSET(str_buf, (char)0xff, sizeof(str_buf));
+ rv = snprintf_hex_buffer(str_buf, 1, HEX_BUF(bytes, 1));
+ TEST_ASSERT_ARRAY_EQ(str_buf, "", sizeof(""));
+ TEST_EQ(rv, -EC_ERROR_OVERFLOW, "%d");
+
+ /* Buffer only has space for one character and '\0'. */
+ memset(str_buf, 0xff, sizeof(str_buf));
+ TEST_ASSERT_MEMSET(str_buf, (char)0xff, sizeof(str_buf));
+ rv = snprintf_hex_buffer(str_buf, 2, HEX_BUF(bytes, 1));
+ TEST_ASSERT_ARRAY_EQ(str_buf, "a", sizeof("a"));
+ TEST_EQ(rv, -EC_ERROR_OVERFLOW, "%d");
- T(expect_success("005e", "%ph", HEX_BUF(bytes, 2)));
- T(expect_success("", "%ph", HEX_BUF(bytes, 0)));
- T(expect_success("00", "%ph", HEX_BUF(bytes, 1)));
return EC_SUCCESS;
}
test_static int test_vsnprintf_combined(void)
{
- T(expect_success("abc", "%c%s", 'a', "bc"));
- T(expect_success("12\tbc", "%d\t%s", 12, "bc"));
+ T(expect_success("abc", "%c%s", 'a', "bc"));
+ T(expect_success("12\tbc", "%d\t%s", 12, "bc"));
+ return EC_SUCCESS;
+}
+
+test_static int test_uint64_to_str(void)
+{
+ /* Longest uin64 in decimal = 20, plus terminating NUL. */
+ char buf[21];
+ char *str;
+
+ str = uint64_to_str(buf, sizeof(buf), /*val=*/0, /*precision=*/-1,
+ /*base=*/10, /*uppercase=*/false);
+ TEST_ASSERT_ARRAY_EQ(str, "0", sizeof("0"));
+
+ str = uint64_to_str(buf, sizeof(buf), /*val=*/UINT64_MAX,
+ /*precision=*/-1, /*base=*/10,
+ /*uppercase=*/false);
+ TEST_ASSERT_ARRAY_EQ(str, "18446744073709551615",
+ sizeof("18446744073709551615"));
+
+ /* Buffer too small by 1. */
+ str = uint64_to_str(buf, /*buf_len=*/20, /*val=*/UINT64_MAX,
+ /*precision=*/-1, /*base=*/10, /*uppercase=*/false);
+ TEST_ASSERT(str == NULL);
+
+ /* lower case hex */
+ str = uint64_to_str(buf, sizeof(buf), /*val=*/0, /*precision=*/-1,
+ /*base=*/16, /*uppercase=*/false);
+ TEST_ASSERT_ARRAY_EQ(str, "0", sizeof("0"));
+
+ /* lower case hex */
+ str = uint64_to_str(buf, sizeof(buf), /*val=*/UINT64_MAX,
+ /*precision=*/-1, /*base=*/16,
+ /*uppercase=*/false);
+ TEST_ASSERT_ARRAY_EQ(str, "ffffffffffffffff",
+ sizeof("fffffffffffffff"));
+
+ /* upper case hex */
+ str = uint64_to_str(buf, sizeof(buf), /*val=*/0, /*precision=*/-1,
+ /*base=*/16, /*uppercase=*/true);
+ TEST_ASSERT_ARRAY_EQ(str, "0", sizeof("0"));
+
+ str = uint64_to_str(buf, sizeof(buf), /*val=*/UINT64_MAX,
+ /*precision=*/-1, /*base=*/16,
+ /*uppercase=*/true);
+ TEST_ASSERT_ARRAY_EQ(str, "FFFFFFFFFFFFFFFF",
+ sizeof("FFFFFFFFFFFFFFF"));
+
+ /* precision 0 */
+ str = uint64_to_str(buf, sizeof(buf), /*val=*/1, /*precision=*/0,
+ /*base=*/10, /*uppercase=*/false);
+ TEST_ASSERT_ARRAY_EQ(str, "1.", sizeof("1."));
+
+ /* precision 6 */
+ str = uint64_to_str(buf, sizeof(buf), /*val=*/1, /*precision=*/6,
+ /*base=*/10, /*uppercase=*/false);
+ TEST_ASSERT_ARRAY_EQ(str, "0.000001", sizeof("0.000001"));
+
+ /* Reduced precision due to buffer that is too small. */
+ str = uint64_to_str(buf, /*buf_len=*/8, /*val=*/1, /*precision=*/6,
+ /*base=*/10, /*uppercase=*/false);
+ TEST_ASSERT_ARRAY_EQ(str, "0.00001", sizeof("0.00001"));
+
+ /*
+ * Reduced precision due to buffer that is too small, so precision
+ * gets changed to 0.
+ */
+ str = uint64_to_str(buf, /*buf_len=*/3, /*val=*/1, /*precision=*/6,
+ /*base=*/10, /*uppercase=*/false);
+ TEST_ASSERT_ARRAY_EQ(str, "1.", sizeof("1."));
+
+ /* Precision is unable to fit in provided buffer. */
+ str = uint64_to_str(buf, /*buf_len=*/2, /*val=*/1, /*precision=*/6,
+ /*base=*/10, /*uppercase=*/false);
+ TEST_ASSERT(str == NULL);
+
+ /* Negative base. */
+ str = uint64_to_str(buf, sizeof(buf), /*val=*/0, /*precision=*/-1,
+ /*base=*/-1, /*uppercase=*/false);
+ TEST_ASSERT(str == NULL);
+
+ /* Base zero. */
+ str = uint64_to_str(buf, sizeof(buf), /*val=*/1, /*precision=*/-1,
+ /*base=*/0, /*uppercase=*/false);
+ TEST_ASSERT(str == NULL);
+
+ /* Base one. */
+ str = uint64_to_str(buf, sizeof(buf), /*val=*/1, /*precision=*/-1,
+ /*base=*/1, /*uppercase=*/false);
+ TEST_ASSERT(str == NULL);
+
+ /* Buffer size 1. */
+ str = uint64_to_str(buf, /*buf_len=*/1, /*val=*/0, /*precision=*/-1,
+ /*base=*/10, /*uppercase=*/false);
+ TEST_ASSERT(str == NULL);
+
+ /* Buffer size 0. */
+ str = uint64_to_str(buf, /*buf_len=*/0, /*val=*/0, /*precision=*/-1,
+ /*base=*/10, /*uppercase=*/false);
+ TEST_ASSERT(str == NULL);
+
+ /* Buffer size -1. */
+ str = uint64_to_str(buf, /*buf_len=*/-1, /*val=*/0, /*precision=*/-1,
+ /*base=*/10, /*uppercase=*/false);
+ TEST_ASSERT(str == NULL);
+
return EC_SUCCESS;
}
-void run_test(int argc, char **argv)
+void run_test(int argc, const char **argv)
{
test_reset();
RUN_TEST(test_vsnprintf_args);
RUN_TEST(test_vsnprintf_int);
+ RUN_TEST(test_printf_long32_enabled);
+ RUN_TEST(test_vsnprintf_long);
RUN_TEST(test_vsnprintf_pointers);
RUN_TEST(test_vsnprintf_chars);
RUN_TEST(test_vsnprintf_strings);
- RUN_TEST(test_vsnprintf_timestamps);
- RUN_TEST(test_vsnprintf_hexdump);
RUN_TEST(test_vsnprintf_combined);
+ RUN_TEST(test_uint64_to_str);
+ RUN_TEST(test_snprintf_timestamp);
+ RUN_TEST(test_snprintf_hex_buffer);
test_print_result();
}