core: Add support for the :_b format specifier.

This groups non-decimal values by fours, bbb_bbbb_bbbb.

The SHOW_COMMA (now SHOW_SEP) flag is overloaded for both
decimal and binary contexts; use of incorrect ":,b" is not
diagnosed, and for ":_d" the separator is still printed as ","
not "_".

Signed-off-by: Jeff Epler <jepler@gmail.com>
pull/13516/head
Jeff Epler 2024-01-25 09:09:06 -06:00
rodzic 307ecc5707
commit 643caba8ce
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: D5BF15AB975AB4DE
6 zmienionych plików z 22 dodań i 7 usunięć

Wyświetl plik

@ -249,8 +249,8 @@ int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char
prefix = prefix_buf; prefix = prefix_buf;
char comma = '\0'; char comma = '\0';
if (flags & PF_FLAG_SHOW_COMMA) { if (flags & PF_FLAG_SHOW_SEP) {
comma = ','; comma = base == 10 ? ',' : '_';
} }
// The size of this buffer is rather arbitrary. If it's not large // The size of this buffer is rather arbitrary. If it's not large

Wyświetl plik

@ -33,7 +33,7 @@
#define PF_FLAG_SPACE_SIGN (0x004) #define PF_FLAG_SPACE_SIGN (0x004)
#define PF_FLAG_NO_TRAILZ (0x008) #define PF_FLAG_NO_TRAILZ (0x008)
#define PF_FLAG_SHOW_PREFIX (0x010) #define PF_FLAG_SHOW_PREFIX (0x010)
#define PF_FLAG_SHOW_COMMA (0x020) #define PF_FLAG_SHOW_SEP (0x020)
#define PF_FLAG_PAD_AFTER_SIGN (0x040) #define PF_FLAG_PAD_AFTER_SIGN (0x040)
#define PF_FLAG_CENTER_ADJUST (0x080) #define PF_FLAG_CENTER_ADJUST (0x080)
#define PF_FLAG_ADD_PERCENT (0x100) #define PF_FLAG_ADD_PERCENT (0x100)

Wyświetl plik

@ -1666,6 +1666,8 @@ size_t mpz_as_str_inpl(const mpz_t *i, unsigned int base, const char *prefix, ch
size_t ilen = i->len; size_t ilen = i->len;
int n_comma = (base == 10) ? 3 : 4;
char *s = str; char *s = str;
if (ilen == 0) { if (ilen == 0) {
if (prefix) { if (prefix) {
@ -1711,7 +1713,7 @@ size_t mpz_as_str_inpl(const mpz_t *i, unsigned int base, const char *prefix, ch
break; break;
} }
} }
if (comma && (s - last_comma) == 3) { if (comma && (s - last_comma) == n_comma) {
*s++ = comma; *s++ = comma;
last_comma = s; last_comma = s;
} }

Wyświetl plik

@ -209,7 +209,7 @@ STATIC const uint8_t log_base2_floor[] = {
size_t mp_int_format_size(size_t num_bits, int base, const char *prefix, char comma) { size_t mp_int_format_size(size_t num_bits, int base, const char *prefix, char comma) {
assert(2 <= base && base <= 16); assert(2 <= base && base <= 16);
size_t num_digits = num_bits / log_base2_floor[base - 1] + 1; size_t num_digits = num_bits / log_base2_floor[base - 1] + 1;
size_t num_commas = comma ? num_digits / 3 : 0; size_t num_commas = comma ? (base == 10 ? num_digits / 3 : num_digits / 4): 0;
size_t prefix_len = prefix ? strlen(prefix) : 0; size_t prefix_len = prefix ? strlen(prefix) : 0;
return num_digits + num_commas + prefix_len + 2; // +1 for sign, +1 for null byte return num_digits + num_commas + prefix_len + 2; // +1 for sign, +1 for null byte
} }
@ -251,6 +251,7 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co
sign = '-'; sign = '-';
} }
int n_comma = (base == 10) ? 3 : 4;
size_t needed_size = mp_int_format_size(sizeof(fmt_int_t) * 8, base, prefix, comma); size_t needed_size = mp_int_format_size(sizeof(fmt_int_t) * 8, base, prefix, comma);
if (needed_size > *buf_size) { if (needed_size > *buf_size) {
*buf = m_new(char, needed_size); *buf = m_new(char, needed_size);
@ -275,7 +276,7 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co
c += '0'; c += '0';
} }
*(--b) = c; *(--b) = c;
if (comma && num != 0 && b > str && (last_comma - b) == 3) { if (comma && num != 0 && b > str && (last_comma - b) == n_comma) {
*(--b) = comma; *(--b) = comma;
last_comma = b; last_comma = b;
} }

Wyświetl plik

@ -1213,7 +1213,11 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
} }
s = str_to_int(s, stop, &width); s = str_to_int(s, stop, &width);
if (*s == ',') { if (*s == ',') {
flags |= PF_FLAG_SHOW_COMMA; flags |= PF_FLAG_SHOW_SEP;
s++;
}
if (*s == '_') {
flags |= PF_FLAG_SHOW_SEP;
s++; s++;
} }
if (*s == '.') { if (*s == '.') {

Wyświetl plik

@ -22,7 +22,15 @@ test("{:4o}", 123)
test("{:4x}", 123) test("{:4x}", 123)
test("{:4X}", 123) test("{:4X}", 123)
test("{:4,d}", 1)
test("{:4_o}", 1)
test("{:4_b}", 1)
test("{:4_x}", 1)
test("{:4,d}", 12345678) test("{:4,d}", 12345678)
test("{:4_o}", 12345678)
test("{:4_b}", 12345678)
test("{:4_x}", 12345678)
test("{:#4b}", 10) test("{:#4b}", 10)
test("{:#4o}", 123) test("{:#4o}", 123)