mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-26 15:59:04 +00:00
Fix padding+minus flag on numbers for printf-family functions (#787)
The C standard states, for conversions using the d, i, b, B, o, u, x or X conversion specifiers: > The precision specifies the minimum number of digits to appear; if > the value being converted can be represented in fewer digits, it is > expanded with leading zeros. - C standard, 7.23.6.1. The fprintf function However, cosmopolitan currently suppresses the addition of leading zeros when the minus flag is set. This is not reflected by anything within the C standard, meaning that behavior is incorrect. This patch fixes this.
This commit is contained in:
parent
2d6ea2fbc9
commit
792b1c84c0
2 changed files with 30 additions and 13 deletions
|
@ -34,17 +34,15 @@ static int __fmt_ntoa_format(int out(const char *, void *, size_t), void *arg,
|
|||
unsigned char flags) {
|
||||
unsigned i;
|
||||
/* pad leading zeros */
|
||||
if (!(flags & FLAGS_LEFT)) {
|
||||
if (width && (flags & FLAGS_ZEROPAD) &&
|
||||
(negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
|
||||
width--;
|
||||
}
|
||||
while ((len < prec) && (len < BUFFER_SIZE)) {
|
||||
buf[len++] = '0';
|
||||
}
|
||||
while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < BUFFER_SIZE)) {
|
||||
buf[len++] = '0';
|
||||
}
|
||||
if (width && (flags & FLAGS_ZEROPAD) &&
|
||||
(negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
|
||||
width--;
|
||||
}
|
||||
while ((len < prec) && (len < BUFFER_SIZE)) {
|
||||
buf[len++] = '0';
|
||||
}
|
||||
while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < BUFFER_SIZE)) {
|
||||
buf[len++] = '0';
|
||||
}
|
||||
/* handle hash */
|
||||
if (flags & FLAGS_HASH) {
|
||||
|
@ -134,8 +132,8 @@ int __fmt_ntoa(int out(const char *, void *, size_t), void *arg, va_list va,
|
|||
bool neg;
|
||||
uint128_t value, sign;
|
||||
|
||||
/* ignore '0' flag when prec is given */
|
||||
if (flags & FLAGS_PRECISION) {
|
||||
/* ignore '0' flag when prec or minus flag is given */
|
||||
if (flags & (FLAGS_PRECISION | FLAGS_LEFT)) {
|
||||
flags &= ~FLAGS_ZEROPAD;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,25 @@ TEST(fmt, d) {
|
|||
EXPECT_STREQ(" 16", _gc(xasprintf("% d", 16)));
|
||||
EXPECT_STREQ(" 2147483647", _gc(xasprintf("% d", INT_MAX)));
|
||||
EXPECT_STREQ("-2147483648", _gc(xasprintf("% d", INT_MIN)));
|
||||
EXPECT_STREQ("042 ", _gc(xasprintf("%-4.3d", 42)));
|
||||
EXPECT_STREQ("-00054", _gc(xasprintf("%-1.5lld", -54ll)));
|
||||
EXPECT_STREQ("00109", _gc(xasprintf("%-.5lld", 109ll)));
|
||||
EXPECT_STREQ("-00116", _gc(xasprintf("%-.5lld", -116ll)));
|
||||
EXPECT_STREQ("00108 ", _gc(xasprintf("%-8.5lld", 108ll)));
|
||||
EXPECT_STREQ("-00054 ", _gc(xasprintf("%-8.5lld", -54ll)));
|
||||
}
|
||||
|
||||
TEST(fmt, u) {
|
||||
EXPECT_STREQ("042 ", _gc(xasprintf("%-4.3u", 42)));
|
||||
}
|
||||
|
||||
TEST(fmt, x) {
|
||||
EXPECT_STREQ("0x01 ", _gc(xasprintf("%#-07.2x", 1)));
|
||||
EXPECT_STREQ("0x00136d ", _gc(xasprintf("%#-010.6x", 4973)));
|
||||
}
|
||||
|
||||
TEST(fmt, b) {
|
||||
EXPECT_STREQ("000010100 ", _gc(xasprintf("%-14.9b", 20)));
|
||||
}
|
||||
|
||||
TEST(fmt, s) {
|
||||
|
|
Loading…
Add table
Reference in a new issue