summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--py/mpprint.c39
-rw-r--r--tests/basics/string_format_sep.py9
2 files changed, 43 insertions, 5 deletions
diff --git a/py/mpprint.c b/py/mpprint.c
index bd7a25087..89b3dbd76 100644
--- a/py/mpprint.c
+++ b/py/mpprint.c
@@ -40,8 +40,20 @@
#include "py/formatfloat.h"
#endif
-static const char pad_spaces[] = " ";
-static const char pad_zeroes[] = "0000000000000000";
+static const char pad_spaces[16] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};
+#define pad_spaces_size (sizeof(pad_spaces))
+static const char pad_common[23] = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '_', '0', '0', '0', ',', '0', '0'};
+// The contents of pad_common is arranged to provide the following padding
+// strings with minimal flash size:
+// 0000000000000000 <- pad_zeroes
+// 0000_000 <- pad_zeroes_underscore (offset: 12, size 5)
+// 000,00 <- pad_zeroes_comma (offset: 17, size 4)
+#define pad_zeroes (pad_common + 0)
+#define pad_zeroes_size (16)
+#define pad_zeroes_underscore (pad_common + 12)
+#define pad_zeroes_underscore_size (5)
+#define pad_zeroes_comma (pad_common + 17)
+#define pad_zeroes_comma_size (4)
static void plat_print_strn(void *env, const char *str, size_t len) {
(void)env;
@@ -65,13 +77,30 @@ int mp_print_strn(const mp_print_t *print, const char *str, size_t len, unsigned
int pad_size;
int total_chars_printed = 0;
const char *pad_chars;
+ char grouping = flags >> PF_FLAG_SEP_POS;
if (!fill || fill == ' ') {
pad_chars = pad_spaces;
- pad_size = sizeof(pad_spaces) - 1;
- } else if (fill == '0') {
+ pad_size = pad_spaces_size;
+ } else if (fill == '0' && !grouping) {
pad_chars = pad_zeroes;
- pad_size = sizeof(pad_zeroes) - 1;
+ pad_size = pad_zeroes_size;
+ } else if (fill == '0') {
+ if (grouping == '_') {
+ pad_chars = pad_zeroes_underscore;
+ pad_size = pad_zeroes_underscore_size;
+ } else {
+ pad_chars = pad_zeroes_comma;
+ pad_size = pad_zeroes_comma_size;
+ }
+ // The result will never start with a grouping character. An extra leading zero is added.
+ // width is dead after this so we can use it in calculation
+ if (width % pad_size == 0) {
+ pad++;
+ width++;
+ }
+ // position the grouping character correctly within the pad repetition
+ pad_chars += pad_size - 1 - width % pad_size;
} else {
// Other pad characters are fairly unusual, so we'll take the hit
// and output them 1 at a time.
diff --git a/tests/basics/string_format_sep.py b/tests/basics/string_format_sep.py
new file mode 100644
index 000000000..de131fdaf
--- /dev/null
+++ b/tests/basics/string_format_sep.py
@@ -0,0 +1,9 @@
+try:
+ "%d" % 1
+except TypeError:
+ print("SKIP")
+ raise SystemExit
+
+for v in (0, 0x10, 0x1000, -0x10, -0x1000):
+ for sz in range(1, 12): print(("{:0%d,d}" % sz).format(v))
+ for sz in range(1, 12): print(("{:0%d_x}" % sz).format(v))