diff options
Diffstat (limited to 'py/objstr.c')
-rw-r--r-- | py/objstr.c | 110 |
1 files changed, 53 insertions, 57 deletions
diff --git a/py/objstr.c b/py/objstr.c index e35fc2976e..50fe10378b 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -34,7 +34,6 @@ #include "py/objlist.h" #include "py/runtime0.h" #include "py/runtime.h" -#include "py/pfenv.h" STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, mp_uint_t n_args, const mp_obj_t *args, mp_obj_t dict); @@ -45,8 +44,7 @@ STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in); /******************************************************************************/ /* str */ -void mp_str_print_quoted(void (*print)(void *env, const char *fmt, ...), void *env, - const byte *str_data, mp_uint_t str_len, bool is_bytes) { +void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, mp_uint_t str_len, bool is_bytes) { // this escapes characters, but it will be very slow to print (calling print many times) bool has_single_quote = false; bool has_double_quote = false; @@ -61,72 +59,72 @@ void mp_str_print_quoted(void (*print)(void *env, const char *fmt, ...), void *e if (has_single_quote && !has_double_quote) { quote_char = '"'; } - print(env, "%c", quote_char); + mp_printf(print, "%c", quote_char); for (const byte *s = str_data, *top = str_data + str_len; s < top; s++) { if (*s == quote_char) { - print(env, "\\%c", quote_char); + mp_printf(print, "\\%c", quote_char); } else if (*s == '\\') { - print(env, "\\\\"); + mp_print_str(print, "\\\\"); } else if (*s >= 0x20 && *s != 0x7f && (!is_bytes || *s < 0x80)) { // In strings, anything which is not ascii control character // is printed as is, this includes characters in range 0x80-0xff // (which can be non-Latin letters, etc.) - print(env, "%c", *s); + mp_printf(print, "%c", *s); } else if (*s == '\n') { - print(env, "\\n"); + mp_print_str(print, "\\n"); } else if (*s == '\r') { - print(env, "\\r"); + mp_print_str(print, "\\r"); } else if (*s == '\t') { - print(env, "\\t"); + mp_print_str(print, "\\t"); } else { - print(env, "\\x%02x", *s); + mp_printf(print, "\\x%02x", *s); } } - print(env, "%c", quote_char); + mp_printf(print, "%c", quote_char); } #if MICROPY_PY_UJSON -void mp_str_print_json(void (*print)(void *env, const char *fmt, ...), void *env, const byte *str_data, mp_uint_t str_len) { +void mp_str_print_json(const mp_print_t *print, const byte *str_data, mp_uint_t str_len) { // for JSON spec, see http://www.ietf.org/rfc/rfc4627.txt // if we are given a valid utf8-encoded string, we will print it in a JSON-conforming way - print(env, "\""); + mp_print_str(print, "\""); for (const byte *s = str_data, *top = str_data + str_len; s < top; s++) { if (*s == '"' || *s == '\\') { - print(env, "\\%c", *s); + mp_printf(print, "\\%c", *s); } else if (*s >= 32) { // this will handle normal and utf-8 encoded chars - print(env, "%c", *s); + mp_printf(print, "%c", *s); } else if (*s == '\n') { - print(env, "\\n"); + mp_print_str(print, "\\n"); } else if (*s == '\r') { - print(env, "\\r"); + mp_print_str(print, "\\r"); } else if (*s == '\t') { - print(env, "\\t"); + mp_print_str(print, "\\t"); } else { // this will handle control chars - print(env, "\\u%04x", *s); + mp_printf(print, "\\u%04x", *s); } } - print(env, "\""); + mp_print_str(print, "\""); } #endif -STATIC void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { +STATIC void str_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { GET_STR_DATA_LEN(self_in, str_data, str_len); #if MICROPY_PY_UJSON if (kind == PRINT_JSON) { - mp_str_print_json(print, env, str_data, str_len); + mp_str_print_json(print, str_data, str_len); return; } #endif bool is_bytes = MP_OBJ_IS_TYPE(self_in, &mp_type_bytes); if (kind == PRINT_STR && !is_bytes) { - print(env, "%.*s", str_len, str_data); + mp_printf(print, "%.*s", str_len, str_data); } else { if (is_bytes) { - print(env, "b"); + mp_print_str(print, "b"); } - mp_str_print_quoted(print, env, str_data, str_len, is_bytes); + mp_str_print_quoted(print, str_data, str_len, is_bytes); } } @@ -145,8 +143,9 @@ mp_obj_t mp_obj_str_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, case 1: { vstr_t vstr; - vstr_init(&vstr, 16); - mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, &vstr, args[0], PRINT_STR); + mp_print_t print; + vstr_init_print(&vstr, 16, &print); + mp_obj_print_helper(&print, args[0], PRINT_STR); return mp_obj_new_str_from_vstr(type_in, &vstr); } @@ -840,10 +839,8 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwa GET_STR_DATA_LEN(args[0], str, len); int arg_i = 0; vstr_t vstr; - vstr_init(&vstr, 16); - pfenv_t pfenv_vstr; - pfenv_vstr.data = &vstr; - pfenv_vstr.print_strn = pfenv_vstr_add_strn; + mp_print_t print; + vstr_init_print(&vstr, 16, &print); for (const byte *top = str + len; str < top; str++) { if (*str == '}') { @@ -998,8 +995,9 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwa } } vstr_t arg_vstr; - vstr_init(&arg_vstr, 16); - mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, &arg_vstr, arg, print_kind); + mp_print_t arg_print; + vstr_init_print(&arg_vstr, 16, &arg_print); + mp_obj_print_helper(&arg_print, arg, print_kind); arg = mp_obj_new_str_from_vstr(&mp_type_str, &arg_vstr); } @@ -1108,20 +1106,20 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwa if (arg_looks_integer(arg)) { switch (type) { case 'b': - pfenv_print_mp_int(&pfenv_vstr, arg, 2, 'a', flags, fill, width, 0); + mp_print_mp_int(&print, arg, 2, 'a', flags, fill, width, 0); continue; case 'c': { char ch = mp_obj_get_int(arg); - pfenv_print_strn(&pfenv_vstr, &ch, 1, flags, fill, width); + mp_print_strn(&print, &ch, 1, flags, fill, width); continue; } case '\0': // No explicit format type implies 'd' case 'n': // I don't think we support locales in uPy so use 'd' case 'd': - pfenv_print_mp_int(&pfenv_vstr, arg, 10, 'a', flags, fill, width, 0); + mp_print_mp_int(&print, arg, 10, 'a', flags, fill, width, 0); continue; case 'o': @@ -1129,12 +1127,12 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwa flags |= PF_FLAG_SHOW_OCTAL_LETTER; } - pfenv_print_mp_int(&pfenv_vstr, arg, 8, 'a', flags, fill, width, 0); + mp_print_mp_int(&print, arg, 8, 'a', flags, fill, width, 0); continue; case 'X': case 'x': - pfenv_print_mp_int(&pfenv_vstr, arg, 16, type - ('X' - 'A'), flags, fill, width, 0); + mp_print_mp_int(&print, arg, 16, type - ('X' - 'A'), flags, fill, width, 0); continue; case 'e': @@ -1206,7 +1204,7 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwa case 'F': case 'g': case 'G': - pfenv_print_float(&pfenv_vstr, mp_obj_get_float(arg), type, flags, fill, width, precision); + mp_print_float(&print, mp_obj_get_float(arg), type, flags, fill, width, precision); break; case '%': @@ -1216,7 +1214,7 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwa #else #define F100 100.0 #endif - pfenv_print_float(&pfenv_vstr, mp_obj_get_float(arg) * F100, 'f', flags, fill, width, precision); + mp_print_float(&print, mp_obj_get_float(arg) * F100, 'f', flags, fill, width, precision); #undef F100 break; #endif @@ -1244,7 +1242,7 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwa switch (type) { case '\0': - mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, &vstr, arg, PRINT_STR); + mp_obj_print_helper(&print, arg, PRINT_STR); break; case 's': { @@ -1256,7 +1254,7 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwa if (slen > (mp_uint_t)precision) { slen = precision; } - pfenv_print_strn(&pfenv_vstr, s, slen, flags, fill, width); + mp_print_strn(&print, s, slen, flags, fill, width); break; } @@ -1282,10 +1280,8 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, mp_uint_t n_args, const mp_o const byte *start_str = str; int arg_i = 0; vstr_t vstr; - vstr_init(&vstr, 16); - pfenv_t pfenv_vstr; - pfenv_vstr.data = &vstr; - pfenv_vstr.print_strn = pfenv_vstr_add_strn; + mp_print_t print; + vstr_init_print(&vstr, 16, &print); for (const byte *top = str + len; str < top; str++) { mp_obj_t arg = MP_OBJ_NULL; @@ -1389,10 +1385,10 @@ not_enough_args: nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "%%c requires int or char")); } - pfenv_print_strn(&pfenv_vstr, s, 1, flags, ' ', width); + mp_print_strn(&print, s, 1, flags, ' ', width); } else if (arg_looks_integer(arg)) { char ch = mp_obj_get_int(arg); - pfenv_print_strn(&pfenv_vstr, &ch, 1, flags, ' ', width); + mp_print_strn(&print, &ch, 1, flags, ' ', width); } else { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "integer required")); @@ -1402,7 +1398,7 @@ not_enough_args: case 'd': case 'i': case 'u': - pfenv_print_mp_int(&pfenv_vstr, arg_as_int(arg), 10, 'a', flags, fill, width, prec); + mp_print_mp_int(&print, arg_as_int(arg), 10, 'a', flags, fill, width, prec); break; #if MICROPY_PY_BUILTINS_FLOAT @@ -1412,7 +1408,7 @@ not_enough_args: case 'F': case 'g': case 'G': - pfenv_print_float(&pfenv_vstr, mp_obj_get_float(arg), *str, flags, fill, width, prec); + mp_print_float(&print, mp_obj_get_float(arg), *str, flags, fill, width, prec); break; #endif @@ -1420,16 +1416,16 @@ not_enough_args: if (alt) { flags |= (PF_FLAG_SHOW_PREFIX | PF_FLAG_SHOW_OCTAL_LETTER); } - pfenv_print_mp_int(&pfenv_vstr, arg, 8, 'a', flags, fill, width, prec); + mp_print_mp_int(&print, arg, 8, 'a', flags, fill, width, prec); break; case 'r': case 's': { vstr_t arg_vstr; - vstr_init(&arg_vstr, 16); - mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, - &arg_vstr, arg, *str == 'r' ? PRINT_REPR : PRINT_STR); + mp_print_t arg_print; + vstr_init_print(&arg_vstr, 16, &arg_print); + mp_obj_print_helper(&arg_print, arg, *str == 'r' ? PRINT_REPR : PRINT_STR); uint vlen = arg_vstr.len; if (prec < 0) { prec = vlen; @@ -1437,14 +1433,14 @@ not_enough_args: if (vlen > (uint)prec) { vlen = prec; } - pfenv_print_strn(&pfenv_vstr, arg_vstr.buf, vlen, flags, ' ', width); + mp_print_strn(&print, arg_vstr.buf, vlen, flags, ' ', width); vstr_clear(&arg_vstr); break; } case 'X': case 'x': - pfenv_print_mp_int(&pfenv_vstr, arg, 16, *str - ('X' - 'A'), flags | alt, fill, width, prec); + mp_print_mp_int(&print, arg, 16, *str - ('X' - 'A'), flags | alt, fill, width, prec); break; default: |