From 208c1020f52e66dcbe0bc8eae1622afb437e69a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Tue, 18 Apr 2023 13:33:30 +0200 Subject: [PATCH] Add 'u' format modifier for unsigned int/hex --- core/string/ustring.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index be829502efc1..a24cff4f11fb 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -4842,6 +4842,7 @@ String String::sprintf(const Array &values, bool *error) const { bool pad_with_zeros = false; bool left_justified = false; bool show_sign = false; + bool as_unsigned = false; if (error) { *error = true; @@ -4882,16 +4883,27 @@ String String::sprintf(const Array &values, bool *error) const { case 'x': break; case 'X': - base = 16; capitalize = true; break; } // Get basic number. - String str = String::num_int64(ABS(value), base, capitalize); + String str; + if (!as_unsigned) { + str = String::num_int64(ABS(value), base, capitalize); + } else { + uint64_t uvalue = *((uint64_t *)&value); + // In unsigned hex, if the value fits in 32 bits, trim it down to that. + if (base == 16 && value < 0 && value >= INT32_MIN) { + uvalue &= 0xffffffff; + } + str = String::num_uint64(uvalue, base, capitalize); + } int number_len = str.length(); + bool negative = value < 0 && !as_unsigned; + // Padding. - int pad_chars_count = (value < 0 || show_sign) ? min_chars - 1 : min_chars; + int pad_chars_count = (negative || show_sign) ? min_chars - 1 : min_chars; String pad_char = pad_with_zeros ? String("0") : String(" "); if (left_justified) { str = str.rpad(pad_chars_count, pad_char); @@ -4900,8 +4912,8 @@ String String::sprintf(const Array &values, bool *error) const { } // Sign. - if (show_sign || value < 0) { - String sign_char = value < 0 ? "-" : "+"; + if (show_sign || negative) { + String sign_char = negative ? "-" : "+"; if (left_justified) { str = str.insert(0, sign_char); } else { @@ -5094,6 +5106,10 @@ String String::sprintf(const Array &values, bool *error) const { show_sign = true; break; } + case 'u': { // Treat as unsigned (for int/hex). + as_unsigned = true; + break; + } case '0': case '1': case '2':