diff options
Diffstat (limited to 'py/objstr.c')
-rw-r--r-- | py/objstr.c | 87 |
1 files changed, 38 insertions, 49 deletions
diff --git a/py/objstr.c b/py/objstr.c index e758dd0062..d4c038a686 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -1,5 +1,5 @@ /* - * This file is part of the Micro Python project, http://micropython.org/ + * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) * @@ -347,8 +347,9 @@ mp_obj_t mp_obj_str_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { rhs_data = bufinfo.buf; rhs_len = bufinfo.len; } else { - // incompatible types - return MP_OBJ_NULL; // op not supported + // LHS is str and RHS has an incompatible type + // (except if operation is EQUAL, but that's handled by mp_obj_equal) + bad_implicit_conversion(rhs_in); } switch (op) { @@ -403,7 +404,7 @@ STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(self_len, index, &slice)) { - mp_not_implemented("only slices with step=1 (aka None) are supported"); + mp_raise_NotImplementedError("only slices with step=1 (aka None) are supported"); } return mp_obj_new_str_of_type(type, self_data + slice.start, slice.stop - slice.start); } @@ -469,6 +470,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { // return joined string return mp_obj_new_str_from_vstr(self_type, &vstr); } +MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join); mp_obj_t mp_obj_str_split(size_t n_args, const mp_obj_t *args) { const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); @@ -544,6 +546,7 @@ mp_obj_t mp_obj_str_split(size_t n_args, const mp_obj_t *args) { return res; } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_split_obj, 1, 3, mp_obj_str_split); #if MICROPY_PY_BUILTINS_STR_SPLITLINES STATIC mp_obj_t str_splitlines(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -589,6 +592,7 @@ STATIC mp_obj_t str_splitlines(size_t n_args, const mp_obj_t *pos_args, mp_map_t return res; } +MP_DEFINE_CONST_FUN_OBJ_KW(str_splitlines_obj, 1, str_splitlines); #endif STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) { @@ -614,7 +618,7 @@ STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) { mp_int_t idx = splits; if (sep == mp_const_none) { - mp_not_implemented("rsplit(None,n)"); + mp_raise_NotImplementedError("rsplit(None,n)"); } else { size_t sep_len; const char *sep_str = mp_obj_str_get_data(sep, &sep_len); @@ -656,6 +660,7 @@ STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) { return MP_OBJ_FROM_PTR(res); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rsplit_obj, 1, 3, str_rsplit); STATIC mp_obj_t str_finder(size_t n_args, const mp_obj_t *args, int direction, bool is_index) { const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); @@ -700,18 +705,22 @@ STATIC mp_obj_t str_finder(size_t n_args, const mp_obj_t *args, int direction, b STATIC mp_obj_t str_find(size_t n_args, const mp_obj_t *args) { return str_finder(n_args, args, 1, false); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj, 2, 4, str_find); STATIC mp_obj_t str_rfind(size_t n_args, const mp_obj_t *args) { return str_finder(n_args, args, -1, false); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rfind_obj, 2, 4, str_rfind); STATIC mp_obj_t str_index(size_t n_args, const mp_obj_t *args) { return str_finder(n_args, args, 1, true); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_index_obj, 2, 4, str_index); STATIC mp_obj_t str_rindex(size_t n_args, const mp_obj_t *args) { return str_finder(n_args, args, -1, true); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rindex_obj, 2, 4, str_rindex); // TODO: (Much) more variety in args STATIC mp_obj_t str_startswith(size_t n_args, const mp_obj_t *args) { @@ -727,12 +736,13 @@ STATIC mp_obj_t str_startswith(size_t n_args, const mp_obj_t *args) { } return mp_obj_new_bool(memcmp(start, prefix, prefix_len) == 0); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_startswith_obj, 2, 3, str_startswith); STATIC mp_obj_t str_endswith(size_t n_args, const mp_obj_t *args) { GET_STR_DATA_LEN(args[0], str, str_len); GET_STR_DATA_LEN(args[1], suffix, suffix_len); if (n_args > 2) { - mp_not_implemented("start/end indices"); + mp_raise_NotImplementedError("start/end indices"); } if (suffix_len > str_len) { @@ -740,6 +750,7 @@ STATIC mp_obj_t str_endswith(size_t n_args, const mp_obj_t *args) { } return mp_obj_new_bool(memcmp(str + (str_len - suffix_len), suffix, suffix_len) == 0); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_endswith_obj, 2, 3, str_endswith); enum { LSTRIP, RSTRIP, STRIP }; @@ -817,14 +828,17 @@ STATIC mp_obj_t str_uni_strip(int type, size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t str_strip(size_t n_args, const mp_obj_t *args) { return str_uni_strip(STRIP, n_args, args); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip); STATIC mp_obj_t str_lstrip(size_t n_args, const mp_obj_t *args) { return str_uni_strip(LSTRIP, n_args, args); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_lstrip_obj, 1, 2, str_lstrip); STATIC mp_obj_t str_rstrip(size_t n_args, const mp_obj_t *args) { return str_uni_strip(RSTRIP, n_args, args); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rstrip_obj, 1, 2, str_rstrip); #if MICROPY_PY_BUILTINS_STR_CENTER STATIC mp_obj_t str_center(mp_obj_t str_in, mp_obj_t width_in) { @@ -841,6 +855,7 @@ STATIC mp_obj_t str_center(mp_obj_t str_in, mp_obj_t width_in) { memcpy(vstr.buf + left, str, str_len); return mp_obj_new_str_from_vstr(mp_obj_get_type(str_in), &vstr); } +MP_DEFINE_CONST_FUN_OBJ_2(str_center_obj, str_center); #endif // Takes an int arg, but only parses unsigned numbers, and only changes @@ -1029,7 +1044,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar arg = key_elem->value; } if (field_name < field_name_top) { - mp_not_implemented("attributes not supported yet"); + mp_raise_NotImplementedError("attributes not supported yet"); } } else { if (*arg_i < 0) { @@ -1064,7 +1079,6 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar arg = mp_obj_new_str_from_vstr(&mp_type_str, &arg_vstr); } - char sign = '\0'; char fill = '\0'; char align = '\0'; int width = -1; @@ -1100,7 +1114,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar } else if (*s == ' ') { flags |= PF_FLAG_SPACE_SIGN; } - sign = *s++; + s++; } if (*s == '#') { flags |= PF_FLAG_SHOW_PREFIX; @@ -1146,7 +1160,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar fill = ' '; } - if (sign) { + if (flags & (PF_FLAG_SHOW_SIGN | PF_FLAG_SPACE_SIGN)) { if (type == 's') { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); @@ -1162,8 +1176,6 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar "sign not allowed with integer format specifier 'c'"); } } - } else { - sign = '-'; } switch (align) { @@ -1346,6 +1358,7 @@ mp_obj_t mp_obj_str_format(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs vstr_t vstr = mp_obj_str_format_helper((const char*)str, (const char*)str + len, &arg_i, n_args, args, kwargs); return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); } +MP_DEFINE_CONST_FUN_OBJ_KW(str_format_obj, 1, mp_obj_str_format); STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_t *args, mp_obj_t dict) { mp_check_self(MP_OBJ_IS_STR_OR_BYTES(pattern)); @@ -1649,6 +1662,7 @@ STATIC mp_obj_t str_replace(size_t n_args, const mp_obj_t *args) { return mp_obj_new_str_from_vstr(self_type, &vstr); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace); STATIC mp_obj_t str_count(size_t n_args, const mp_obj_t *args) { const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); @@ -1689,6 +1703,7 @@ STATIC mp_obj_t str_count(size_t n_args, const mp_obj_t *args) { return MP_OBJ_NEW_SMALL_INT(num_occurrences); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count); #if MICROPY_PY_BUILTINS_STR_PARTITION STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, int direction) { @@ -1736,10 +1751,12 @@ STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, int direction) { STATIC mp_obj_t str_partition(mp_obj_t self_in, mp_obj_t arg) { return str_partitioner(self_in, arg, 1); } +MP_DEFINE_CONST_FUN_OBJ_2(str_partition_obj, str_partition); STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) { return str_partitioner(self_in, arg, -1); } +MP_DEFINE_CONST_FUN_OBJ_2(str_rpartition_obj, str_rpartition); #endif // Supposedly not too critical operations, so optimize for code size @@ -1757,10 +1774,12 @@ STATIC mp_obj_t str_caseconv(unichar (*op)(unichar), mp_obj_t self_in) { STATIC mp_obj_t str_lower(mp_obj_t self_in) { return str_caseconv(unichar_tolower, self_in); } +MP_DEFINE_CONST_FUN_OBJ_1(str_lower_obj, str_lower); STATIC mp_obj_t str_upper(mp_obj_t self_in) { return str_caseconv(unichar_toupper, self_in); } +MP_DEFINE_CONST_FUN_OBJ_1(str_upper_obj, str_upper); STATIC mp_obj_t str_uni_istype(bool (*f)(unichar), mp_obj_t self_in) { GET_STR_DATA_LEN(self_in, self_data, self_len); @@ -1798,22 +1817,27 @@ STATIC mp_obj_t str_uni_istype(bool (*f)(unichar), mp_obj_t self_in) { STATIC mp_obj_t str_isspace(mp_obj_t self_in) { return str_uni_istype(unichar_isspace, self_in); } +MP_DEFINE_CONST_FUN_OBJ_1(str_isspace_obj, str_isspace); STATIC mp_obj_t str_isalpha(mp_obj_t self_in) { return str_uni_istype(unichar_isalpha, self_in); } +MP_DEFINE_CONST_FUN_OBJ_1(str_isalpha_obj, str_isalpha); STATIC mp_obj_t str_isdigit(mp_obj_t self_in) { return str_uni_istype(unichar_isdigit, self_in); } +MP_DEFINE_CONST_FUN_OBJ_1(str_isdigit_obj, str_isdigit); STATIC mp_obj_t str_isupper(mp_obj_t self_in) { return str_uni_istype(unichar_isupper, self_in); } +MP_DEFINE_CONST_FUN_OBJ_1(str_isupper_obj, str_isupper); STATIC mp_obj_t str_islower(mp_obj_t self_in) { return str_uni_istype(unichar_islower, self_in); } +MP_DEFINE_CONST_FUN_OBJ_1(str_islower_obj, str_islower); #if MICROPY_CPYTHON_COMPAT // These methods are superfluous in the presence of str() and bytes() @@ -1829,6 +1853,7 @@ STATIC mp_obj_t bytes_decode(size_t n_args, const mp_obj_t *args) { } return mp_obj_str_make_new(&mp_type_str, n_args, 0, args); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_decode_obj, 1, 3, bytes_decode); // TODO: should accept kwargs too STATIC mp_obj_t str_encode(size_t n_args, const mp_obj_t *args) { @@ -1841,6 +1866,7 @@ STATIC mp_obj_t str_encode(size_t n_args, const mp_obj_t *args) { } return bytes_make_new(NULL, n_args, 0, args); } +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj, 1, 3, str_encode); #endif mp_int_t mp_obj_str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { @@ -1859,43 +1885,6 @@ mp_int_t mp_obj_str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_u } } -#if MICROPY_CPYTHON_COMPAT -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_decode_obj, 1, 3, bytes_decode); -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj, 1, 3, str_encode); -#endif -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj, 2, 4, str_find); -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rfind_obj, 2, 4, str_rfind); -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_index_obj, 2, 4, str_index); -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rindex_obj, 2, 4, str_rindex); -MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join); -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_split_obj, 1, 3, mp_obj_str_split); -#if MICROPY_PY_BUILTINS_STR_SPLITLINES -MP_DEFINE_CONST_FUN_OBJ_KW(str_splitlines_obj, 1, str_splitlines); -#endif -#if MICROPY_PY_BUILTINS_STR_CENTER -MP_DEFINE_CONST_FUN_OBJ_2(str_center_obj, str_center); -#endif -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rsplit_obj, 1, 3, str_rsplit); -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_startswith_obj, 2, 3, str_startswith); -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_endswith_obj, 2, 3, str_endswith); -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip); -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_lstrip_obj, 1, 2, str_lstrip); -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rstrip_obj, 1, 2, str_rstrip); -MP_DEFINE_CONST_FUN_OBJ_KW(str_format_obj, 1, mp_obj_str_format); -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace); -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count); -#if MICROPY_PY_BUILTINS_STR_PARTITION -MP_DEFINE_CONST_FUN_OBJ_2(str_partition_obj, str_partition); -MP_DEFINE_CONST_FUN_OBJ_2(str_rpartition_obj, str_rpartition); -#endif -MP_DEFINE_CONST_FUN_OBJ_1(str_lower_obj, str_lower); -MP_DEFINE_CONST_FUN_OBJ_1(str_upper_obj, str_upper); -MP_DEFINE_CONST_FUN_OBJ_1(str_isspace_obj, str_isspace); -MP_DEFINE_CONST_FUN_OBJ_1(str_isalpha_obj, str_isalpha); -MP_DEFINE_CONST_FUN_OBJ_1(str_isdigit_obj, str_isdigit); -MP_DEFINE_CONST_FUN_OBJ_1(str_isupper_obj, str_isupper); -MP_DEFINE_CONST_FUN_OBJ_1(str_islower_obj, str_islower); - STATIC const mp_rom_map_elem_t str8_locals_dict_table[] = { #if MICROPY_CPYTHON_COMPAT { MP_ROM_QSTR(MP_QSTR_decode), MP_ROM_PTR(&bytes_decode_obj) }, |