Skip to content

Commit 8eda19a

Browse files
pabigotcarlescufi
authored andcommitted
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 <[email protected]>
1 parent b036afb commit 8eda19a

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

lib/os/cbprintf_complete.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,21 +79,31 @@ enum specifier_cat_enum {
7979
SPECIFIER_FP,
8080
};
8181

82+
#define CHAR_IS_SIGNED (CHAR_MIN != 0)
83+
#if CHAR_IS_SIGNED
84+
#define CASE_SINT_CHAR case 'c':
85+
#define CASE_UINT_CHAR
86+
#else
87+
#define CASE_SINT_CHAR
88+
#define CASE_UINT_CHAR case 'c':
89+
#endif
90+
8291
/* Case label to identify conversions for signed integral values. The
8392
* corresponding argument_value tag is sint and category is
8493
* SPECIFIER_SINT.
8594
*/
8695
#define SINT_CONV_CASES \
8796
'd': \
97+
CASE_SINT_CHAR \
8898
case 'i'
8999

90100
/* Case label to identify conversions for signed integral arguments.
91101
* The corresponding argument_value tag is uint and category is
92102
* SPECIFIER_UINT.
93103
*/
94104
#define UINT_CONV_CASES \
95-
'c': \
96-
case 'o': \
105+
'o': \
106+
CASE_UINT_CHAR \
97107
case 'u': \
98108
case 'x': \
99109
case 'X'
@@ -1515,7 +1525,7 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
15151525
}
15161526
case 'c':
15171527
bps = buf;
1518-
buf[0] = value->uint;
1528+
buf[0] = CHAR_IS_SIGNED ? value->sint : value->uint;
15191529
bpe = buf + 1;
15201530
break;
15211531
case 'd':

0 commit comments

Comments
 (0)