fmt: if enabled, group padding zeroes.

Before this commit, the combination of `_` and `0` format characters
would produce a result like `000000001010_1010`.
After this commit, it would be `0000_0000_1010_1010`.

This has a slight quirk where a format like `{:020_b}` results in
the output `0_0000_0000_1010_1010`, which is one character longer than
requested. Python has the same behavior, and it's not clear what would
be strictly speaking correct, so Python behavior is implemented.
This commit is contained in:
Catherine 2024-03-28 10:06:18 +00:00 committed by Marcelina Kościelnicka
parent 27cb4c52b4
commit 94170388a9
2 changed files with 23 additions and 11 deletions

View File

@ -1109,28 +1109,27 @@ struct fmt_part {
}
}
size_t width = Bits;
size_t val_width = Bits;
if (base != 10) {
width = 1;
val_width = 1;
for (size_t index = 0; index < Bits; index++)
if (val.bit(index))
width = index + 1;
val_width = index + 1;
}
if (base == 2) {
if (show_base)
prefix += "0b";
for (size_t index = 0; index < width; index++) {
for (size_t index = 0; index < val_width; index++) {
if (group && index > 0 && index % 4 == 0)
buf += '_';
buf += (val.bit(index) ? '1' : '0');
}
std::reverse(buf.begin(), buf.end());
} else if (base == 8 || base == 16) {
if (show_base)
prefix += (base == 16) ? (hex_upper ? "0X" : "0x") : "0o";
size_t step = (base == 16) ? 4 : 3;
for (size_t index = 0; index < width; index += step) {
for (size_t index = 0; index < val_width; index += step) {
if (group && index > 0 && index % (4 * step) == 0)
buf += '_';
uint8_t value = val.bit(index) | (val.bit(index + 1) << 1) | (val.bit(index + 2) << 2);
@ -1138,7 +1137,6 @@ struct fmt_part {
value |= val.bit(index + 3) << 3;
buf += (hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[value];
}
std::reverse(buf.begin(), buf.end());
} else if (base == 10) {
if (show_base)
prefix += "0d";
@ -1158,8 +1156,16 @@ struct fmt_part {
xval = quotient;
index++;
}
std::reverse(buf.begin(), buf.end());
} else assert(false && "Unsupported base for fmt_part");
if (justify == NUMERIC && group && padding == '0') {
int group_size = base == 10 ? 3 : 4;
while (prefix.size() + buf.size() < width) {
if (buf.size() % (group_size + 1) == group_size)
buf += '_';
buf += '0';
}
}
std::reverse(buf.begin(), buf.end());
break;
}

View File

@ -776,7 +776,6 @@ std::string Fmt::render() const
else /* if (bit == State::S0) */
buf += '0';
}
std::reverse(buf.begin(), buf.end());
} else if (part.base == 8 || part.base == 16) {
if (part.show_base)
prefix += (part.base == 16) ? (part.hex_upper ? "0X" : "0x") : "0o";
@ -807,7 +806,6 @@ std::string Fmt::render() const
else
buf += (part.hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[subvalue.as_int()];
}
std::reverse(buf.begin(), buf.end());
} else if (part.base == 10) {
if (part.show_base)
prefix += "0d";
@ -831,9 +829,17 @@ std::string Fmt::render() const
value = RTLIL::const_div(value, 10, false, false, value.size());
index++;
}
std::reverse(buf.begin(), buf.end());
}
} else log_abort();
if (part.justify == FmtPart::NUMERIC && part.group && part.padding == '0') {
int group_size = part.base == 10 ? 3 : 4;
while (prefix.size() + buf.size() < part.width) {
if (buf.size() % (group_size + 1) == group_size)
buf += '_';
buf += '0';
}
}
std::reverse(buf.begin(), buf.end());
} else if (part.type == FmtPart::STRING) {
buf = part.sig.as_const().decode_string();
} else if (part.type == FmtPart::VLOG_TIME) {