format: fix transcription of zero values to strings

an iteration condition terminated the write when a value was zero rather
than when all numerals were written. instead, iterate over the remaining
numerals.

fixes printf("%zu", 0u)
This commit is contained in:
Danny Robson 2016-08-10 17:38:39 +10:00
parent 00eca4445b
commit de48f75e96
2 changed files with 6 additions and 2 deletions

View File

@ -743,6 +743,7 @@ namespace util { namespace format { namespace detail {
const auto numerals = digits (t, spec.base); const auto numerals = digits (t, spec.base);
const auto characters = numerals + (spec.positive_char ? 1 : 0); const auto characters = numerals + (spec.positive_char ? 1 : 0);
CHECK_NEZ (numerals);
// add any requested positive signifier // add any requested positive signifier
if (spec.positive_char) if (spec.positive_char)
@ -775,11 +776,13 @@ namespace util { namespace format { namespace detail {
// output is blank (though space padding/etc is still preserved). // output is blank (though space padding/etc is still preserved).
if (t != 0 || spec.precision != 0) { if (t != 0 || spec.precision != 0) {
const char *NUMERALS = spec.uppercase ? const char *NUMERALS = spec.uppercase ?
"0123456789ABCDEF" : "0123456789ABCDEF":
"0123456789abcdef"; "0123456789abcdef";
char buffer[numerals]; char buffer[numerals];
for (auto cursor = buffer; t; t /= spec.base) size_t remain = numerals;
for (auto cursor = buffer; remain--; t /= spec.base)
*cursor++ = NUMERALS[t % spec.base]; *cursor++ = NUMERALS[t % spec.base];
std::reverse_copy (buffer, buffer + numerals, os); std::reverse_copy (buffer, buffer + numerals, os);
} }

View File

@ -53,6 +53,7 @@ main (void)
CHECK_RENDER ("%lu", "1", (unsigned long)1); CHECK_RENDER ("%lu", "1", (unsigned long)1);
CHECK_RENDER ("%llu", "1", (unsigned long long)1); CHECK_RENDER ("%llu", "1", (unsigned long long)1);
CHECK_RENDER ("%ju", "1", (uintmax_t)1); CHECK_RENDER ("%ju", "1", (uintmax_t)1);
CHECK_RENDER ("%zu", "0", (size_t)0);
CHECK_RENDER ("%zu", "1", (size_t)1); CHECK_RENDER ("%zu", "1", (size_t)1);
CHECK_RENDER ("%o", "1", 01u); CHECK_RENDER ("%o", "1", 01u);