diff --git a/libc/fmt/ntoa.c b/libc/fmt/ntoa.c index 8b1878df0..acace9793 100644 --- a/libc/fmt/ntoa.c +++ b/libc/fmt/ntoa.c @@ -46,8 +46,8 @@ static int __fmt_ntoa_format(int out(const char *, void *, size_t), void *arg, } /* handle hash */ if (flags & FLAGS_HASH) { - if (!(flags & FLAGS_PRECISION) && len && - ((len == prec) || (len == width)) && buf[len - 1] == '0') { + if ((!(flags & FLAGS_PRECISION) || log2base == 3) && len && + ((len >= prec) || (len >= width)) && buf[len - 1] == '0') { len--; if (len && (log2base == 4 || log2base == 1) && buf[len - 1] == '0') { len--; @@ -95,7 +95,9 @@ int __fmt_ntoa2(int out(const char *, void *, size_t), void *arg, unsigned len, count, digit; char buf[BUFFER_SIZE]; len = 0; - if (!value) flags &= ~FLAGS_HASH; + /* we check for log2base != 3 because otherwise we'll print nothing for a value of 0 with precision 0 when # mandates that one be printed */ + if (!value && log2base != 3) + flags &= ~FLAGS_HASH; if (value || !(flags & FLAGS_PRECISION)) { count = 0; do { diff --git a/test/libc/fmt/fmt_test.c b/test/libc/fmt/fmt_test.c index 4f481d44f..69b5827ce 100644 --- a/test/libc/fmt/fmt_test.c +++ b/test/libc/fmt/fmt_test.c @@ -80,6 +80,13 @@ TEST(fmt, x) { EXPECT_STREQ("0x00136d ", _gc(xasprintf("%#-010.6x", 4973))); } +TEST(fmt, o) { + EXPECT_STREQ("0000000000000037777777634", _gc(xasprintf("%#.25o", -100))); + EXPECT_STREQ("0001777777777777777777634", _gc(xasprintf("%#.25lo", -100L))); + EXPECT_STREQ("0001777777777777777777634", _gc(xasprintf("%#.25llo", -100LL))); + EXPECT_STREQ("0", _gc(xasprintf("%#.o", 0))); +} + TEST(fmt, b) { EXPECT_STREQ("000010100 ", _gc(xasprintf("%-14.9b", 20))); }