Skip to content

Commit fd2fa8a

Browse files
committed
mpprint: Correctly format leading zeros with separators.
The new padding patterns for commas-and-zeroes and underscores-and- zeroes are smooshed together into the existing pad_zeroes to save space. Only the two combinations of (decimal + commas) and (other bases + underscores) are properly supported. Add a test for it. Closes micropython#18082 Signed-off-by: Jeff Epler <jepler@unpythonic.net>
1 parent 6681530 commit fd2fa8a

2 files changed

Lines changed: 30 additions & 5 deletions

File tree

py/mpprint.c

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,13 @@
4040
#include "py/formatfloat.h"
4141
#endif
4242

43-
static const char pad_spaces[] = " ";
44-
static const char pad_zeroes[] = "0000000000000000";
43+
static const char pad_spaces[16] = " ";
44+
static const char pad_zeroes[23] = "0000000000000000_000,00";
45+
// 0000000000000000 <- pad_zeros
46+
// 0000_000 <- pad_zeros_comma (offset: 12)
47+
// 000,00 <- pad_zeros_comma (offset: 17)
48+
#define pad_zeroes_comma (pad_zeroes + 17)
49+
#define pad_zeroes_underscore (pad_zeroes + 12)
4550

4651
static void plat_print_strn(void *env, const char *str, size_t len) {
4752
(void)env;
@@ -65,13 +70,29 @@ int mp_print_strn(const mp_print_t *print, const char *str, size_t len, unsigned
6570
int pad_size;
6671
int total_chars_printed = 0;
6772
const char *pad_chars;
73+
char comma = flags >> PF_FLAG_SEP_POS;
6874

6975
if (!fill || fill == ' ') {
7076
pad_chars = pad_spaces;
71-
pad_size = sizeof(pad_spaces) - 1;
72-
} else if (fill == '0') {
77+
pad_size = sizeof(pad_spaces);
78+
} else if (fill == '0' && !comma) {
7379
pad_chars = pad_zeroes;
74-
pad_size = sizeof(pad_zeroes) - 1;
80+
pad_size = 16;
81+
} else if (fill == '0') {
82+
if (comma == '_') {
83+
pad_chars = pad_zeroes_underscore;
84+
pad_size = 5;
85+
} else {
86+
pad_chars = pad_zeroes_comma;
87+
pad_size = 4;
88+
}
89+
// The result will never start with a comma. An extra leading zero is added.
90+
if (width % pad_size == 0) {
91+
pad++;
92+
width++;
93+
}
94+
// position the comma correctly within the pad repetition
95+
pad_chars += pad_size - 1 - width % pad_size;
7596
} else {
7697
// Other pad characters are fairly unusual, so we'll take the hit
7798
// and output them 1 at a time.

tests/basics/string_format_sep.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
for v in (0, 0x10, 0x1000):
2+
for sz in range(1, 12): print(("{:0%d,d}" % sz).format(v))
3+
#for sz in range(1, 12): print(("{:0%d_x}" % sz).format(v))
4+

0 commit comments

Comments
 (0)