diff options
author | Tom Hughes <tomhughes@chromium.org> | 2022-07-12 15:31:34 -0700 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-07-14 23:30:52 +0000 |
commit | fd2f9f554ecc9f729708f216153edff49715a828 (patch) | |
tree | a96cbdbba5d7f792233ed89f15c80afb2f4d6c47 /common/printf.c | |
parent | 26e3fe318448df383d5decf09f76a6c04786afc4 (diff) | |
download | chrome-ec-fd2f9f554ecc9f729708f216153edff49715a828.tar.gz |
printf: Create separate function for converting uint64_t to string
Move the logic for converting a uint64_t to a string into a separate
function so that it can be used in a followup commit for converting
timestamps. The printf logic should behave exactly as before, although
there is additional error checking.
BRANCH=none
BUG=b:238433667, b:234181908
TEST=make run-printf
Signed-off-by: Tom Hughes <tomhughes@chromium.org>
Change-Id: I1f8fd92859d8a7b4b97dbddd1a1009a0e6500047
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3760663
Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
Diffstat (limited to 'common/printf.c')
-rw-r--r-- | common/printf.c | 96 |
1 files changed, 61 insertions, 35 deletions
diff --git a/common/printf.c b/common/printf.c index b44ffdbafd..d16c561f5f 100644 --- a/common/printf.c +++ b/common/printf.c @@ -35,6 +35,64 @@ static int hexdigit(int c) #define PF_SIGN BIT(2) /* Add sign (+) for a positive number */ #define PF_64BIT BIT(3) /* Number is 64-bit */ +test_export_static char *uint64_to_str(char *buf, int buf_len, uint64_t val, + int precision, int base, bool uppercase) +{ + int i; + char *str; + + if (buf_len <= 1) + return NULL; + + if (base <= 1) + return NULL; + + /* + * Convert integer to string, starting at end of + * buffer and working backwards. + */ + str = buf + buf_len - 1; + *(str) = '\0'; + + /* + * Fixed-point precision must fit in our buffer. + * Leave space for "0." and the terminating null. + */ + if (precision > buf_len - 3) { + precision = buf_len - 3; + if (precision < 0) + return NULL; + } + + /* + * Handle digits to right of decimal for fixed point numbers. + */ + for (i = 0; i < precision; i++) + *(--str) = '0' + uint64divmod(&val, 10); + if (precision >= 0) + *(--str) = '.'; + + if (!val) + *(--str) = '0'; + + while (val) { + int digit; + + if (str <= buf) + return NULL; + + digit = uint64divmod(&val, base); + if (digit < 10) + *(--str) = '0' + digit; + else if (uppercase) + *(--str) = 'A' + digit - 10; + else + *(--str) = 'a' + digit - 10; + } + + return str; +} + /* * Print the buffer as a string of bytes in hex. * Returns 0 on success or an error on failure. @@ -345,41 +403,9 @@ int vfnprintf(int (*addchar)(void *context, int c), void *context, if (format == error_str) continue; /* Bad format specifier */ - /* - * Convert integer to string, starting at end of - * buffer and working backwards. - */ - vstr = intbuf + sizeof(intbuf) - 1; - *(vstr) = '\0'; - - /* - * Fixed-point precision must fit in our buffer. - * Leave space for "0." and the terminating null. - */ - if (precision > (int)(sizeof(intbuf) - 3)) - precision = sizeof(intbuf) - 3; - - /* - * Handle digits to right of decimal for fixed point - * numbers. - */ - for (vlen = 0; vlen < precision; vlen++) - *(--vstr) = '0' + uint64divmod(&v, 10); - if (precision >= 0) - *(--vstr) = '.'; - - if (!v) - *(--vstr) = '0'; - - while (v) { - int digit = uint64divmod(&v, base); - if (digit < 10) - *(--vstr) = '0' + digit; - else if (c == 'X') - *(--vstr) = 'A' + digit - 10; - else - *(--vstr) = 'a' + digit - 10; - } + vstr = uint64_to_str(intbuf, sizeof(intbuf), v, + precision, base, c == 'X'); + ASSERT(vstr); if (sign) *(--vstr) = sign; |