Fix str.modulo when precision is specified.
This commit is contained in:
parent
380f147d2e
commit
b69f9fa31f
14
py/objstr.c
14
py/objstr.c
@ -981,7 +981,7 @@ mp_obj_t mp_obj_str_format(uint n_args, const mp_obj_t *args) {
|
|||||||
if (arg_looks_integer(arg)) {
|
if (arg_looks_integer(arg)) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'b':
|
case 'b':
|
||||||
pfenv_print_mp_int(&pfenv_vstr, arg, 1, 2, 'a', flags, fill, width);
|
pfenv_print_mp_int(&pfenv_vstr, arg, 1, 2, 'a', flags, fill, width, 0);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
@ -994,7 +994,7 @@ mp_obj_t mp_obj_str_format(uint n_args, const mp_obj_t *args) {
|
|||||||
case '\0': // No explicit format type implies 'd'
|
case '\0': // No explicit format type implies 'd'
|
||||||
case 'n': // I don't think we support locales in uPy so use 'd'
|
case 'n': // I don't think we support locales in uPy so use 'd'
|
||||||
case 'd':
|
case 'd':
|
||||||
pfenv_print_mp_int(&pfenv_vstr, arg, 1, 10, 'a', flags, fill, width);
|
pfenv_print_mp_int(&pfenv_vstr, arg, 1, 10, 'a', flags, fill, width, 0);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
@ -1002,12 +1002,12 @@ mp_obj_t mp_obj_str_format(uint n_args, const mp_obj_t *args) {
|
|||||||
flags |= PF_FLAG_SHOW_OCTAL_LETTER;
|
flags |= PF_FLAG_SHOW_OCTAL_LETTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
pfenv_print_mp_int(&pfenv_vstr, arg, 1, 8, 'a', flags, fill, width);
|
pfenv_print_mp_int(&pfenv_vstr, arg, 1, 8, 'a', flags, fill, width, 0);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'X':
|
case 'X':
|
||||||
case 'x':
|
case 'x':
|
||||||
pfenv_print_mp_int(&pfenv_vstr, arg, 1, 16, type - ('X' - 'A'), flags, fill, width);
|
pfenv_print_mp_int(&pfenv_vstr, arg, 1, 16, type - ('X' - 'A'), flags, fill, width, 0);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
@ -1255,7 +1255,7 @@ not_enough_args:
|
|||||||
case 'd':
|
case 'd':
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'u':
|
case 'u':
|
||||||
pfenv_print_mp_int(&pfenv_vstr, arg_as_int(arg), 1, 10, 'a', flags, fill, width);
|
pfenv_print_mp_int(&pfenv_vstr, arg_as_int(arg), 1, 10, 'a', flags, fill, width, prec);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if MICROPY_PY_BUILTINS_FLOAT
|
#if MICROPY_PY_BUILTINS_FLOAT
|
||||||
@ -1273,7 +1273,7 @@ not_enough_args:
|
|||||||
if (alt) {
|
if (alt) {
|
||||||
flags |= (PF_FLAG_SHOW_PREFIX | PF_FLAG_SHOW_OCTAL_LETTER);
|
flags |= (PF_FLAG_SHOW_PREFIX | PF_FLAG_SHOW_OCTAL_LETTER);
|
||||||
}
|
}
|
||||||
pfenv_print_mp_int(&pfenv_vstr, arg, 1, 8, 'a', flags, fill, width);
|
pfenv_print_mp_int(&pfenv_vstr, arg, 1, 8, 'a', flags, fill, width, prec);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
@ -1296,7 +1296,7 @@ not_enough_args:
|
|||||||
|
|
||||||
case 'X':
|
case 'X':
|
||||||
case 'x':
|
case 'x':
|
||||||
pfenv_print_mp_int(&pfenv_vstr, arg, 1, 16, *str - ('X' - 'A'), flags | alt, fill, width);
|
pfenv_print_mp_int(&pfenv_vstr, arg, 1, 16, *str - ('X' - 'A'), flags | alt, fill, width, prec);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
52
py/pfenv.c
52
py/pfenv.c
@ -91,8 +91,10 @@ int pfenv_print_strn(const pfenv_t *pfenv, const char *str, unsigned int len, in
|
|||||||
left_pad -= p;
|
left_pad -= p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (len) {
|
||||||
pfenv->print_strn(pfenv->data, str, len);
|
pfenv->print_strn(pfenv->data, str, len);
|
||||||
total_chars_printed += len;
|
total_chars_printed += len;
|
||||||
|
}
|
||||||
if (right_pad > 0) {
|
if (right_pad > 0) {
|
||||||
total_chars_printed += right_pad;
|
total_chars_printed += right_pad;
|
||||||
while (right_pad > 0) {
|
while (right_pad > 0) {
|
||||||
@ -181,13 +183,19 @@ int pfenv_print_int(const pfenv_t *pfenv, machine_uint_t x, int sgn, int base, i
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pfenv_print_mp_int(const pfenv_t *pfenv, mp_obj_t x, int sgn, int base, int base_char, int flags, char fill, int width) {
|
int pfenv_print_mp_int(const pfenv_t *pfenv, mp_obj_t x, int sgn, int base, int base_char, int flags, char fill, int width, int prec) {
|
||||||
if (!MP_OBJ_IS_INT(x)) {
|
if (!MP_OBJ_IS_INT(x)) {
|
||||||
// This will convert booleans to int, or raise an error for
|
// This will convert booleans to int, or raise an error for
|
||||||
// non-integer types.
|
// non-integer types.
|
||||||
x = MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(x));
|
x = MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((flags & (PF_FLAG_LEFT_ADJUST | PF_FLAG_CENTER_ADJUST)) == 0 && fill == '0') {
|
||||||
|
if (prec > width) {
|
||||||
|
width = prec;
|
||||||
|
}
|
||||||
|
prec = 0;
|
||||||
|
}
|
||||||
char prefix_buf[4];
|
char prefix_buf[4];
|
||||||
char *prefix = prefix_buf;
|
char *prefix = prefix_buf;
|
||||||
|
|
||||||
@ -230,6 +238,9 @@ int pfenv_print_mp_int(const pfenv_t *pfenv, mp_obj_t x, int sgn, int base, int
|
|||||||
int fmt_size = 0;
|
int fmt_size = 0;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
|
if (prec > 1) {
|
||||||
|
flags |= PF_FLAG_PAD_AFTER_SIGN;
|
||||||
|
}
|
||||||
char sign = '\0';
|
char sign = '\0';
|
||||||
if (flags & PF_FLAG_PAD_AFTER_SIGN) {
|
if (flags & PF_FLAG_PAD_AFTER_SIGN) {
|
||||||
// We add the pad in this function, so since the pad goes after
|
// We add the pad in this function, so since the pad goes after
|
||||||
@ -245,7 +256,39 @@ int pfenv_print_mp_int(const pfenv_t *pfenv, mp_obj_t x, int sgn, int base, int
|
|||||||
x, base, prefix, base_char, comma);
|
x, base, prefix, base_char, comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int spaces_before = 0;
|
||||||
|
int spaces_after = 0;
|
||||||
|
|
||||||
|
if (prec > 1) {
|
||||||
|
// If prec was specified, then prec specifies the width to zero-pad the
|
||||||
|
// the number to. This zero-padded number then gets left or right
|
||||||
|
// aligned in width characters.
|
||||||
|
|
||||||
|
int prec_width = fmt_size; // The digits
|
||||||
|
if (prec_width < prec) {
|
||||||
|
prec_width = prec;
|
||||||
|
}
|
||||||
|
if (flags & PF_FLAG_PAD_AFTER_SIGN) {
|
||||||
|
if (sign) {
|
||||||
|
prec_width++;
|
||||||
|
}
|
||||||
|
prec_width += prefix_len;
|
||||||
|
}
|
||||||
|
if (prec_width < width) {
|
||||||
|
if (flags & PF_FLAG_LEFT_ADJUST) {
|
||||||
|
spaces_after = width - prec_width;
|
||||||
|
} else {
|
||||||
|
spaces_before = width - prec_width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fill = '0';
|
||||||
|
flags &= ~PF_FLAG_LEFT_ADJUST;
|
||||||
|
}
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
if (spaces_before) {
|
||||||
|
len += pfenv_print_strn(pfenv, "", 0, 0, ' ', spaces_before);
|
||||||
|
}
|
||||||
if (flags & PF_FLAG_PAD_AFTER_SIGN) {
|
if (flags & PF_FLAG_PAD_AFTER_SIGN) {
|
||||||
// pad after sign implies pad after prefix as well.
|
// pad after sign implies pad after prefix as well.
|
||||||
if (sign) {
|
if (sign) {
|
||||||
@ -257,9 +300,16 @@ int pfenv_print_mp_int(const pfenv_t *pfenv, mp_obj_t x, int sgn, int base, int
|
|||||||
width -= prefix_len;
|
width -= prefix_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (prec > 1) {
|
||||||
|
width = prec;
|
||||||
|
}
|
||||||
|
|
||||||
len += pfenv_print_strn(pfenv, str, fmt_size, flags, fill, width);
|
len += pfenv_print_strn(pfenv, str, fmt_size, flags, fill, width);
|
||||||
|
|
||||||
|
if (spaces_after) {
|
||||||
|
len += pfenv_print_strn(pfenv, "", 0, 0, ' ', spaces_after);
|
||||||
|
}
|
||||||
|
|
||||||
if (buf != stack_buf) {
|
if (buf != stack_buf) {
|
||||||
m_free(buf, buf_size);
|
m_free(buf, buf_size);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ void pfenv_vstr_add_strn(void *data, const char *str, unsigned int len);
|
|||||||
|
|
||||||
int pfenv_print_strn(const pfenv_t *pfenv, const char *str, unsigned int len, int flags, char fill, int width);
|
int pfenv_print_strn(const pfenv_t *pfenv, const char *str, unsigned int len, int flags, char fill, int width);
|
||||||
int pfenv_print_int(const pfenv_t *pfenv, machine_uint_t x, int sgn, int base, int base_char, int flags, char fill, int width);
|
int pfenv_print_int(const pfenv_t *pfenv, machine_uint_t x, int sgn, int base, int base_char, int flags, char fill, int width);
|
||||||
int pfenv_print_mp_int(const pfenv_t *pfenv, mp_obj_t x, int sgn, int base, int base_char, int flags, char fill, int width);
|
int pfenv_print_mp_int(const pfenv_t *pfenv, mp_obj_t x, int sgn, int base, int base_char, int flags, char fill, int width, int prec);
|
||||||
#if MICROPY_PY_BUILTINS_FLOAT
|
#if MICROPY_PY_BUILTINS_FLOAT
|
||||||
int pfenv_print_float(const pfenv_t *pfenv, mp_float_t f, char fmt, int flags, char fill, int width, int prec);
|
int pfenv_print_float(const pfenv_t *pfenv, mp_float_t f, char fmt, int flags, char fill, int width, int prec);
|
||||||
#endif
|
#endif
|
||||||
|
@ -51,8 +51,18 @@ print("%#06x" % 18)
|
|||||||
|
|
||||||
print("%*d" % (5, 10))
|
print("%*d" % (5, 10))
|
||||||
print("%*.*d" % (2, 2, 20))
|
print("%*.*d" % (2, 2, 20))
|
||||||
# TODO: Formatted incorrectly
|
print("%*.*d" % (5, 8, 20))
|
||||||
#print("%*.*d" % (5, 8, 20))
|
|
||||||
|
print(">%8.4d<" % -12)
|
||||||
|
print(">% 8.4d<" % -12)
|
||||||
|
print(">%+8.4d<" % 12)
|
||||||
|
print(">%+8.4d<" % -12)
|
||||||
|
print(">%08.4d<" % -12)
|
||||||
|
print(">%08.4d<" % 12)
|
||||||
|
print(">%-8.4d<" % -12)
|
||||||
|
print(">%-08.4d<" % -12)
|
||||||
|
print(">%-+08.4d<" % -12)
|
||||||
|
print(">%-+08.4d<" % 12)
|
||||||
|
|
||||||
# Cases when "*" used and there's not enough values total
|
# Cases when "*" used and there's not enough values total
|
||||||
try:
|
try:
|
||||||
|
Loading…
Reference in New Issue
Block a user