[PATCH 6/6] lib: Provide a signed version of simple_itoa()
Simon Glass
sjg at chromium.org
Wed Mar 19 12:59:08 CET 2025
In some cases we want to show a signed value to the user without needing
to use the full printf() implementation. Add a new version of the
simple_itoa() function to handle this.
Update the existing function to use ulong instead of long, to avoid
confusion about which it actually uses.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
include/vsprintf.h | 14 ++++++++++++++
lib/vsprintf.c | 29 +++++++++++++++++++++++++----
test/lib/str.c | 17 ++++++++++++++++-
3 files changed, 55 insertions(+), 5 deletions(-)
diff --git a/include/vsprintf.h b/include/vsprintf.h
index 9da6ce7cc4d..cd079684572 100644
--- a/include/vsprintf.h
+++ b/include/vsprintf.h
@@ -219,6 +219,20 @@ int vsprintf(char *buf, const char *fmt, va_list args);
*/
char *simple_itoa(ulong val);
+/**
+ * simple_itoa_signed() - convert a signed integer to a string
+ *
+ * This returns a static string containing the decimal representation of the
+ * given value. The returned value may be overwritten by other calls to other
+ * simple... functions, so should be used immediately
+ *
+ * If the value is negative, a minus sign ('-') is prepended
+ *
+ * @val: Value to convert
+ * Return: string containing the signed decimal representation of @val
+ */
+char *simple_itoa_signed(long i);
+
/**
* simple_xtoa() - convert an unsigned integer to a hex string
*
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index c7340a047b2..478d445a569 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -845,21 +845,42 @@ int vprintf(const char *fmt, va_list args)
}
#endif
-static char local_toa[22];
+static char local_toa[23];
-char *simple_itoa(ulong i)
+char *simple_itoa_(ulong i, bool use_signed)
{
- /* 21 digits plus null terminator, good for 64-bit or smaller ints */
- char *p = &local_toa[21];
+ /*
+ * 21 digits plus sign and null terminator, good for 64-bit or smaller
+ * ints
+ */
+ char *p = &local_toa[22];
+ bool neg = false;
+ if (use_signed && (long)i < 0) {
+ i = -i;
+ neg = true;
+ }
*p-- = '\0';
do {
*p-- = '0' + i % 10;
i /= 10;
} while (i > 0);
+
+ if (neg)
+ *p-- = '-';
return p + 1;
}
+char *simple_itoa(ulong i)
+{
+ return simple_itoa_(i, false);
+}
+
+char *simple_itoa_signed(long i)
+{
+ return simple_itoa_(i, true);
+}
+
char *simple_xtoa(ulong num)
{
/* 16 digits plus nul terminator, good for 64-bit or smaller ints */
diff --git a/test/lib/str.c b/test/lib/str.c
index e62045318c0..d6d29bbf3eb 100644
--- a/test/lib/str.c
+++ b/test/lib/str.c
@@ -221,14 +221,29 @@ static int str_itoa(struct unit_test_state *uts)
ut_asserteq_str("123", simple_itoa(123));
ut_asserteq_str("0", simple_itoa(0));
ut_asserteq_str("2147483647", simple_itoa(0x7fffffff));
- ut_asserteq_str("4294967295", simple_itoa(0xffffffff));
+ ut_asserteq_str("2147483647", simple_itoa_signed(0x7fffffff));
+ ut_asserteq_str("2147483648", simple_itoa(0x80000000));
+ if (IS_ENABLED(CONFIG_PHYS_64BIT)) {
+ ut_asserteq_str("2147483648", simple_itoa_signed(0x80000000));
+ ut_asserteq_str("4294967295", simple_itoa_signed(0xffffffff));
+ } else {
+ ut_asserteq_str("-2147483648", simple_itoa_signed(0x80000000));
+ ut_asserteq_str("-1", simple_itoa_signed(0xffffffff));
+ }
/* Use #ifdef here to avoid a compiler warning on 32-bit machines */
#ifdef CONFIG_PHYS_64BIT
if (sizeof(ulong) == 8) {
ut_asserteq_str("9223372036854775807",
simple_itoa((1UL << 63) - 1));
+ ut_asserteq_str("9223372036854775807",
+ simple_itoa_signed((1UL << 63) - 1));
+ ut_asserteq_str("9223372036854775808",
+ simple_itoa((1UL << 63)));
+ ut_asserteq_str("-9223372036854775808",
+ simple_itoa_signed((1UL << 63)));
ut_asserteq_str("18446744073709551615", simple_itoa(-1));
+ ut_asserteq_str("-1", simple_itoa_signed(-1));
}
#endif /* CONFIG_PHYS_64BIT */
--
2.43.0
More information about the U-Boot
mailing list