summaryrefslogtreecommitdiff
path: root/common/printf.c
diff options
context:
space:
mode:
authorTom Hughes <tomhughes@chromium.org>2022-07-12 15:31:34 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-07-14 23:30:52 +0000
commitfd2f9f554ecc9f729708f216153edff49715a828 (patch)
treea96cbdbba5d7f792233ed89f15c80afb2f4d6c47 /common/printf.c
parent26e3fe318448df383d5decf09f76a6c04786afc4 (diff)
downloadchrome-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.c96
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;