From 8eda19a898c39a1a226f53367b9ec1d4f99fc19e Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Wed, 6 Jan 2021 10:59:49 -0600 Subject: [PATCH] lib: os: cbprintf: correctly handle signed vs unsigned char Whether char is signed or unsigned is toolchain and target specific. Rather than assume it's signed (which is true for x86, but not for ARM), do the right thing based on whether the minimum representable value is less than zero. Signed-off-by: Peter Bigot --- lib/os/cbprintf_complete.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/os/cbprintf_complete.c b/lib/os/cbprintf_complete.c index e0e02a6f006..a19db423df9 100644 --- a/lib/os/cbprintf_complete.c +++ b/lib/os/cbprintf_complete.c @@ -79,12 +79,22 @@ enum specifier_cat_enum { SPECIFIER_FP, }; +#define CHAR_IS_SIGNED (CHAR_MIN != 0) +#if CHAR_IS_SIGNED +#define CASE_SINT_CHAR case 'c': +#define CASE_UINT_CHAR +#else +#define CASE_SINT_CHAR +#define CASE_UINT_CHAR case 'c': +#endif + /* Case label to identify conversions for signed integral values. The * corresponding argument_value tag is sint and category is * SPECIFIER_SINT. */ #define SINT_CONV_CASES \ 'd': \ + CASE_SINT_CHAR \ case 'i' /* Case label to identify conversions for signed integral arguments. @@ -92,8 +102,8 @@ enum specifier_cat_enum { * SPECIFIER_UINT. */ #define UINT_CONV_CASES \ - 'c': \ - case 'o': \ + 'o': \ + CASE_UINT_CHAR \ case 'u': \ case 'x': \ case 'X' @@ -1515,7 +1525,7 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap) } case 'c': bps = buf; - buf[0] = value->uint; + buf[0] = CHAR_IS_SIGNED ? value->sint : value->uint; bpe = buf + 1; break; case 'd':